@mastra/server-adapters-test-suite 0.1.3-alpha.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["z","z3","Mastra","z","Mastra","Mastra","Mastra"],"sources":["../src/route-test-utils.ts","../src/route-test-suite.ts","../src/test-helpers.ts","../src/route-adapter-test-suite.ts","../src/mcp-route-test-suite.ts","../src/native-mcp-fixture.ts","../src/mcp-transport-test-suite.ts","../src/multipart-test-suite.ts","../src/http-logging-test-suite.ts","../src/body-limit-test-suite.ts"],"sourcesContent":["import { getZodTypeName, getZodDef } from '@mastra/core/utils';\nimport type { ServerRoute } from '@mastra/server/server-adapter';\nimport type { z, ZodSchema } from 'zod';\n\n/**\n * Normalizes a route path to ensure consistent formatting.\n * - Removes leading/trailing whitespace\n * - Validates no path traversal (..), query strings (?), or fragments (#)\n * - Collapses multiple consecutive slashes\n * - Removes trailing slashes\n * - Ensures leading slash (unless empty)\n *\n * @param path - The route path to normalize\n * @returns The normalized path (empty string for root paths)\n * @throws Error if path contains invalid characters\n */\nexport function normalizeRoutePath(path: string): string {\n let normalized = path.trim();\n if (normalized.includes('..') || normalized.includes('?') || normalized.includes('#')) {\n throw new Error(`Invalid route path: \"${path}\". Path cannot contain '..', '?', or '#'`);\n }\n normalized = normalized.replace(/\\/+/g, '/');\n if (normalized === '/' || normalized === '') {\n return '';\n }\n if (normalized.endsWith('/')) {\n normalized = normalized.slice(0, -1);\n }\n if (!normalized.startsWith('/')) {\n normalized = `/${normalized}`;\n }\n return normalized;\n}\n\n/**\n * Provide valid schema values for routes whose fields have cross-field constraints.\n */\nexport function getRouteSpecificSchemaDefaults(route: ServerRoute): {\n query?: Record<string, unknown>;\n body?: Record<string, unknown>;\n} {\n if (route.path === '/observability/traces/query/values') {\n return { body: { predicateScope: 'trace', path: 'entityName' } };\n }\n\n if (route.path === '/datasets/:datasetId/compare') {\n return { body: { experimentIds: ['test-experiment-a', 'test-experiment-b'], baselineId: 'test-experiment-a' } };\n }\n\n return {};\n}\n\n/**\n * Generate context-aware test value based on field name\n */\nexport function generateContextualValue(fieldName?: string): string {\n if (!fieldName) return 'test-string';\n\n const field = fieldName.toLowerCase();\n\n // Timestamp fields used in body validation need a valid ISO string.\n if (field === 'createdat' || field === 'updatedat') return new Date().toISOString();\n\n if (field === 'entitytype') return 'AGENT';\n if (field === 'entityid') return 'test-agent';\n if (field === 'role') return 'user';\n // Cron fields must be a valid cron expression (schedule create routes).\n if (field === 'cron') return '* * * * *';\n if (field === 'fields') return 'result'; // For workflow execution result field filtering (status is always included)\n // JSON-encoded query params (wrapped with wrapSchemaForQueryParams)\n if (field === 'tags') return '[\"test-tag\"]'; // For observability traces filtering\n\n // Email fields need valid email format\n if (field === 'email' || field.includes('email')) return 'test@example.com';\n\n // Version comparison query params (from/to are version IDs)\n // Both use the same known version ID - comparing a version to itself returns empty diffs,\n // which is valid for route integration tests that verify the endpoint responds correctly\n if (field === 'from') return 'test-version-id';\n if (field === 'to') return 'test-version-id';\n\n // Workspace filesystem - content and query fields\n if (field === 'content') return 'test content'; // For write/index operations\n if (field === 'query') return 'test'; // For search operations\n\n if (field.includes('agent')) return 'test-agent';\n if (field.includes('workflow')) return 'test-workflow';\n if (field.includes('tool') && field.includes('slug')) return 'test-tool-slug';\n if (field.includes('tool')) return 'test-tool';\n if (field.includes('skill')) return 'test-skill';\n if (field.includes('reference') && field.includes('path')) return 'test-reference.md';\n if (field.includes('thread')) return 'test-thread';\n if (field === 'conversationid') return 'test-thread';\n if (field.includes('resource')) return 'test-resource';\n if (field.includes('run')) return 'test-run';\n if (field.includes('step')) return 'test-step';\n if (field.includes('task')) return 'test-task';\n if (field.includes('scorer') || field.includes('score')) return 'test-scorer';\n if (field.includes('processor')) return 'test-processor';\n if (field.includes('trace')) return 'test-trace';\n if (field.includes('span')) return 'test-span';\n if (field.includes('vector')) return 'test-vector';\n if (field.includes('index')) return 'test-index';\n if (field.includes('message')) return 'test-message';\n if (field === 'responseid') return 'test-response';\n if (field.includes('transport')) return 'test-transport';\n if (field === 'reorderedmodelids') return 'id1';\n if (field.includes('model')) return 'openai/gpt-4o';\n if (field.includes('action')) return 'merge-template';\n if (field.includes('entity')) return 'test-entity';\n if (field.includes('provider')) return 'test-provider';\n if (field.includes('dataset') && field.includes('version')) return '1';\n if (field.includes('dataset')) return 'test-dataset';\n if (field.includes('item')) return 'test-item';\n if (field.includes('experiment')) return 'test-experiment';\n if (field.includes('mcp') && field.includes('client')) return 'test-mcp-client';\n if (field.includes('prompt') && field.includes('block')) return 'test-prompt-block';\n if (field.includes('block')) return 'test-prompt-block';\n if (field === 'uri') return 'ui://test/app';\n\n return 'test-string';\n}\n\n/**\n * Generate valid test data from a Zod schema\n */\nexport function generateValidDataFromSchema(schema: z.ZodTypeAny, fieldName?: string): any {\n let typeName = getZodTypeName(schema);\n let def = getZodDef(schema);\n\n // Unwrap effects first\n while (typeName === 'ZodEffects') {\n schema = def.schema;\n typeName = getZodTypeName(schema);\n def = getZodDef(schema);\n }\n\n // Unwrap z.preprocess / .transform pipes (Zod 4 represents these as ZodPipe\n // with the validated schema at `def.out`). Without this the generator falls\n // through to `undefined` for any query schema that uses a top-level\n // preprocess (e.g. legacy-shape back-compat shims).\n while (typeName === 'ZodPipe' && def?.out) {\n schema = getZodTypeName(def.out) === 'ZodTransform' ? def.in : def.out;\n typeName = getZodTypeName(schema);\n def = getZodDef(schema);\n }\n\n if (typeName === 'ZodOptional' || typeName === 'ZodNullable') {\n return generateValidDataFromSchema(def.innerType, fieldName);\n }\n if (typeName === 'ZodDefault') {\n if ('_zod' in schema) {\n return def.defaultValue;\n } else {\n return def.defaultValue();\n }\n }\n\n if (typeName === 'ZodString') {\n const hasDateTimeFormat = (def.checks ?? []).some((check: any) => {\n const checkDef = check._zod?.def ?? check.def ?? check;\n return check.kind === 'datetime' || check.format === 'datetime' || checkDef.format === 'datetime';\n });\n if (hasDateTimeFormat) {\n if (fieldName?.toLowerCase() === 'from') return '2026-01-01T00:00:00.000Z';\n if (fieldName?.toLowerCase() === 'to') return '2026-01-02T00:00:00.000Z';\n return '2026-01-01T00:00:00.000Z';\n }\n return generateContextualValue(fieldName);\n }\n if (typeName === 'ZodNumber') {\n // Respect min/max constraints from Zod checks\n let min = -Infinity;\n let max = Infinity;\n let minInclusive = true;\n let maxInclusive = true;\n let requiresInt = false;\n let requiresSafeInt = false;\n let multipleOf: number | undefined;\n const checks = def.checks ?? [];\n for (const check of checks) {\n // Zod 3: check.kind === 'min'/'max', check.value\n if (check.kind === 'min') {\n min = check.value;\n minInclusive = check.inclusive ?? true;\n }\n if (check.kind === 'max') {\n max = check.value;\n maxInclusive = check.inclusive ?? true;\n }\n if (check.kind === 'int') requiresInt = true;\n if (check.kind === 'multipleOf') multipleOf = check.value;\n // Zod 4: checks have _zod.def with check type and value\n const zod4Def = check._zod?.def;\n if (zod4Def) {\n if (zod4Def.check === 'greater_than') {\n min = zod4Def.value;\n minInclusive = false;\n }\n if (zod4Def.check === 'greater_than_or_equal') {\n min = zod4Def.value;\n minInclusive = true;\n }\n if (zod4Def.check === 'less_than') {\n max = zod4Def.value;\n maxInclusive = false;\n }\n if (zod4Def.check === 'less_than_or_equal') {\n max = zod4Def.value;\n maxInclusive = true;\n }\n if (zod4Def.check === 'multiple_of') multipleOf = zod4Def.value;\n if (zod4Def.check === 'integer') requiresInt = true;\n if (zod4Def.check === 'safeint') {\n requiresSafeInt = true;\n requiresInt = true;\n }\n // Zod 4 emits `int()` as `number_format` with `format: 'int' | 'safeint'`.\n if (zod4Def.check === 'number_format') {\n if (zod4Def.format === 'int' || zod4Def.format === 'safeint') {\n requiresInt = true;\n if (zod4Def.format === 'safeint') requiresSafeInt = true;\n }\n }\n }\n }\n\n const step = requiresInt || requiresSafeInt ? 1 : 0.1;\n const effectiveMin = min === -Infinity ? min : minInclusive ? min : min + step;\n const effectiveMax = max === Infinity ? max : maxInclusive ? max : max - step;\n\n const clampToRange = (value: number): number => {\n if (effectiveMin !== -Infinity && value < effectiveMin) return effectiveMin;\n if (effectiveMax !== Infinity && value > effectiveMax) return effectiveMax;\n return value;\n };\n\n let candidate: number;\n if (effectiveMin !== -Infinity && effectiveMax !== Infinity) {\n candidate = (effectiveMin + effectiveMax) / 2;\n } else if (effectiveMin !== -Infinity) {\n candidate = effectiveMin;\n } else if (effectiveMax !== Infinity) {\n candidate = effectiveMax;\n } else {\n candidate = requiresInt ? 10 : 10.5;\n }\n\n candidate = clampToRange(candidate);\n\n if (multipleOf && multipleOf > 0) {\n const minBase = effectiveMin !== -Infinity ? effectiveMin : 0;\n const maxBase = effectiveMax !== Infinity ? effectiveMax : minBase + multipleOf * 10;\n let aligned = Math.ceil(minBase / multipleOf) * multipleOf;\n if (effectiveMin !== -Infinity && aligned < effectiveMin) {\n aligned += multipleOf;\n }\n if (effectiveMax !== Infinity && aligned > effectiveMax) {\n aligned = Math.floor(maxBase / multipleOf) * multipleOf;\n }\n candidate = aligned;\n }\n\n if (requiresInt) {\n candidate = Math.round(candidate);\n candidate = clampToRange(candidate);\n }\n\n if (requiresSafeInt) {\n candidate = Math.min(Math.max(candidate, Number.MIN_SAFE_INTEGER), Number.MAX_SAFE_INTEGER);\n }\n\n return candidate;\n }\n if (typeName === 'ZodBoolean') return true;\n if (typeName === 'ZodNull') return null;\n if (typeName === 'ZodUndefined') return undefined;\n if (typeName === 'ZodDate') return new Date();\n if (typeName === 'ZodBigInt') return BigInt(0);\n\n if (typeName === 'ZodLiteral') {\n if ('_zod' in schema) {\n return def.values?.[0];\n } else {\n return def.value;\n }\n }\n\n if (typeName === 'ZodEnum') {\n if ('_zod' in schema) {\n return Object.values(def.entries)[0];\n } else {\n return def.values[0];\n }\n }\n if (typeName === 'ZodNativeEnum') {\n const values = Object.values(def.values);\n return values[0];\n }\n\n if (typeName === 'ZodArray') {\n if ('_zod' in schema) {\n return [generateValidDataFromSchema(def.element, fieldName)];\n } else {\n return [generateValidDataFromSchema(def.type, fieldName)];\n }\n }\n\n if (typeName === 'ZodObject') {\n const shape = typeof def.shape === 'function' ? def.shape() : def.shape;\n const obj: any = {};\n for (const [key, fieldSchema] of Object.entries(shape)) {\n const fieldTypeName = getZodTypeName(fieldSchema as z.ZodTypeAny);\n if (fieldTypeName === 'ZodOptional') {\n // Special case: workflow routes need inputData field even when optional\n // because _run.start() expects { inputData?, ... } structure, not just {}\n // Without this, z.object({}).safeParse(undefined) fails with \"Required\" error\n if (key === 'inputData' || key === 'agent_id') {\n const fieldDef = getZodDef(fieldSchema as z.ZodTypeAny);\n const innerType = fieldDef.innerType;\n obj[key] = generateValidDataFromSchema(innerType, key);\n }\n continue;\n }\n obj[key] = generateValidDataFromSchema(fieldSchema as z.ZodTypeAny, key);\n }\n return obj;\n }\n\n if (typeName === 'ZodRecord') {\n return { key: generateValidDataFromSchema(def.valueType, fieldName) };\n }\n\n if (typeName === 'ZodUnion') {\n // Special case: for content field in messages, use string format (simpler and more reliable)\n if (fieldName === 'content') {\n // Check if one of the options is ZodString\n for (const option of def.options) {\n if (getZodTypeName(option) === 'ZodString') {\n return 'test message content';\n }\n }\n }\n return generateValidDataFromSchema(def.options[0], fieldName);\n }\n\n if (typeName === 'ZodDiscriminatedUnion') {\n const options = Array.from(def.options.values());\n return generateValidDataFromSchema(options[0] as z.ZodTypeAny, fieldName);\n }\n\n if (typeName === 'ZodIntersection') {\n const left = generateValidDataFromSchema(def.left, fieldName);\n const right = generateValidDataFromSchema(def.right, fieldName);\n return { ...left, ...right };\n }\n\n if (typeName === 'ZodTuple') {\n return def.items.map((item: z.ZodTypeAny) => generateValidDataFromSchema(item, fieldName));\n }\n\n if (typeName === 'ZodAny' || typeName === 'ZodUnknown') {\n if (fieldName === 'content') {\n return [{ type: 'text', text: 'test message content' }];\n }\n // Special case: message parts for processor messages\n if (fieldName === 'parts') {\n return [{ type: 'text', text: 'test message part' }];\n }\n // Special case: workflow inputData is z.unknown() but needs to be an object\n // to match the workflow's inputSchema (typically z.object({}))\n if (fieldName === 'inputData') {\n return {};\n }\n // Special case: memory messages are z.any() but handler validates they have threadId/resourceId\n // Note: This assumes we're generating a single message in an array context\n if (fieldName === 'messages') {\n return {\n role: 'user',\n content: [{ type: 'text', text: 'test message' }],\n threadId: 'test-thread',\n resourceId: 'test-resource',\n };\n }\n return 'test-value';\n }\n\n return undefined;\n}\n\nexport function getDefaultValidPathParams(route: ServerRoute): Record<string, any> {\n const params: Record<string, any> = {};\n\n // For stored agent routes (versions), use 'test-stored-agent' to match test context\n // For regular agent routes, use 'test-agent'\n if (route.path.includes(':agentId') && route.path.includes('/stored/agents/')) {\n params.agentId = 'test-stored-agent';\n } else if (route.path.includes(':agentId')) {\n params.agentId = 'test-agent';\n }\n if (route.path.includes(':workflowId')) params.workflowId = 'test-workflow';\n if (route.path.includes(':scheduleId')) params.scheduleId = 'test-schedule';\n if (route.path.includes(':backgroundTaskId')) params.backgroundTaskId = 'test-background-task-id';\n if (route.path.includes(':toolId')) params.toolId = 'test-tool';\n if (route.path.includes(':threadId')) params.threadId = 'test-thread';\n if (route.path.includes(':conversationId')) params.conversationId = 'test-thread';\n if (route.path.includes(':controllerId')) params.controllerId = 'test-controller';\n if (route.path.includes(':responseId')) params.responseId = 'test-response';\n if (route.path.includes(':resourceId')) params.resourceId = 'test-resource';\n if (route.path.includes(':modelConfigId')) params.modelConfigId = 'id1';\n // For stored scorer version routes, use the stored scorer ID to match test context\n if (route.path.includes(':scorerId') && route.path.includes('/stored/scorers/')) {\n params.scorerId = 'test-stored-scorer';\n } else if (route.path.includes(':scorerId')) {\n params.scorerId = 'test-scorer';\n }\n if (route.path.includes(':scoreId')) params.scoreId = 'test-score';\n if (route.path.includes(':feedbackId')) params.feedbackId = 'test-feedback';\n if (route.path.includes(':traceId')) params.traceId = 'test-trace';\n if (route.path.includes(':runId')) params.runId = 'test-run';\n if (route.path.includes(':stepId')) params.stepId = 'test-step';\n if (route.path.includes(':taskId')) params.taskId = 'test-task-id';\n if (route.path.includes(':vectorName')) params.vectorName = 'test-vector';\n if (route.path.includes(':indexName')) params.indexName = 'test-index';\n if (route.path.includes(':transportId')) params.transportId = 'test-transport';\n if (route.path.includes(':spanId')) params.spanId = 'test-span';\n if (route.path.includes(':entityType')) params.entityType = 'AGENT';\n if (route.path.includes(':entityId')) params.entityId = 'test-agent';\n if (route.path.includes(':actionId')) params.actionId = 'merge-template';\n if (route.path.includes(':storedAgentId')) params.storedAgentId = 'test-stored-agent';\n if (route.path.includes(':storedScorerId')) params.storedScorerId = 'test-stored-scorer';\n if (route.path.includes(':roleId')) params.roleId = 'test-role';\n if (route.path.includes(':versionId')) params.versionId = 'test-version-id';\n if (route.path.includes(':processorId')) params.processorId = 'test-processor';\n // MCP route params - need to get actual server ID from test context\n if (route.path.includes(':id') && route.path.includes('/mcp/v0/servers/')) params.id = 'test-server-1';\n if (route.path.includes(':serverId')) params.serverId = 'test-server-1';\n if (route.path.includes(':toolId') && route.path.includes('/mcp/')) params.toolId = 'getWeather';\n\n // Workspace route params\n if (route.path.includes(':workspaceId')) params.workspaceId = 'test-workspace';\n\n // Skills route params\n if (route.path.includes(':skillName')) params.skillName = 'test-skill';\n if (route.path.includes(':referencePath')) params.referencePath = 'test-reference.md';\n\n // Stored entity route params\n if (route.path.includes(':storedMCPClientId')) params.storedMCPClientId = 'test-stored-mcp-client';\n if (route.path.includes(':mcpClientId')) params.mcpClientId = 'test-stored-mcp-client';\n if (route.path.includes(':storedPromptBlockId')) params.storedPromptBlockId = 'test-stored-prompt-block';\n if (route.path.includes(':promptBlockId')) params.promptBlockId = 'test-stored-prompt-block';\n if (route.path.includes(':storedWorkspaceId')) params.storedWorkspaceId = 'test-stored-workspace';\n if (route.path.includes(':storedSkillId')) params.storedSkillId = 'test-stored-skill';\n if (route.path.includes(':dynamicWorkflowId')) params.dynamicWorkflowId = 'test-dynamic-workflow';\n if (route.path.includes(':scorerId') && route.path.includes('/stored/scorers/'))\n params.scorerId = 'test-stored-scorer';\n\n // Dataset route params\n if (route.path.includes(':datasetId')) params.datasetId = 'test-dataset';\n if (route.path.includes(':itemId')) params.itemId = 'test-item';\n if (route.path.includes(':experimentId')) params.experimentId = 'test-experiment';\n if (route.path.includes(':resultId')) params.resultId = 'test-result';\n if (route.path.includes(':datasetVersion')) params.datasetVersion = '1';\n\n // Tool provider route params\n if (route.path.includes(':providerId')) params.providerId = 'test-provider';\n if (route.path.includes(':toolSlug')) params.toolSlug = 'test-tool-slug';\n if (route.path.includes(':authId')) params.authId = 'test-auth-id';\n if (route.path.includes(':connectionId')) params.connectionId = 'test-connection-id';\n\n // Channel route params\n if (route.path.includes(':platform')) params.platform = 'test-platform';\n\n // Builder registry route params\n if (route.path.includes(':registryId')) params.registryId = 'skills-sh';\n\n return params;\n}\n\nexport function getDefaultInvalidPathParams(route: ServerRoute): Array<Record<string, any>> {\n const invalid: Array<Record<string, any>> = [];\n invalid.push({});\n\n if (route.path.includes(':agentId')) {\n invalid.push({ agentId: 123 });\n }\n\n if (route.path.includes(':registryId')) {\n invalid.push({ registryId: 123 });\n }\n\n return invalid;\n}\n\n/**\n * Validate that a value matches a schema\n */\nexport function expectValidSchema(schema: ZodSchema, value: unknown) {\n const result = schema.safeParse(value);\n if (!result.success) {\n throw new Error(`Schema validation failed: ${JSON.stringify(result.error.issues, null, 2)}`);\n }\n}\n\n/**\n * Validate that a value does NOT match a schema\n */\nexport function expectInvalidSchema(schema: ZodSchema, value: unknown) {\n const result = schema.safeParse(value);\n if (result.success) {\n throw new Error(`Expected schema validation to fail, but it succeeded`);\n }\n}\n\n/**\n * Validate route metadata\n */\nexport function validateRouteMetadata(\n route: ServerRoute,\n expected: {\n method?: string;\n path?: string;\n responseType?: ServerRoute['responseType'];\n hasPathParams?: boolean;\n hasQueryParams?: boolean;\n hasBody?: boolean;\n hasResponse?: boolean;\n hasOpenAPI?: boolean;\n },\n) {\n if (expected.method && route.method !== expected.method) {\n throw new Error(`Expected method ${expected.method} but got ${route.method}`);\n }\n\n if (expected.path && route.path !== expected.path) {\n throw new Error(`Expected path ${expected.path} but got ${route.path}`);\n }\n\n if (expected.responseType && route.responseType !== expected.responseType) {\n throw new Error(`Expected responseType ${expected.responseType} but got ${route.responseType}`);\n }\n\n if (expected.hasPathParams !== undefined) {\n const hasPathParams = !!route.pathParamSchema;\n if (hasPathParams !== expected.hasPathParams) {\n throw new Error(\n `Expected pathParamSchema to be ${expected.hasPathParams ? 'defined' : 'undefined'} but got ${hasPathParams ? 'defined' : 'undefined'}`,\n );\n }\n }\n\n if (expected.hasQueryParams !== undefined) {\n const hasQueryParams = !!route.queryParamSchema;\n if (hasQueryParams !== expected.hasQueryParams) {\n throw new Error(\n `Expected queryParamSchema to be ${expected.hasQueryParams ? 'defined' : 'undefined'} but got ${hasQueryParams ? 'defined' : 'undefined'}`,\n );\n }\n }\n\n if (expected.hasBody !== undefined) {\n const hasBody = !!route.bodySchema;\n if (hasBody !== expected.hasBody) {\n throw new Error(\n `Expected bodySchema to be ${expected.hasBody ? 'defined' : 'undefined'} but got ${hasBody ? 'defined' : 'undefined'}`,\n );\n }\n }\n\n if (expected.hasResponse !== undefined) {\n const hasResponse = !!route.responseSchema;\n if (hasResponse !== expected.hasResponse) {\n throw new Error(\n `Expected responseSchema to be ${expected.hasResponse ? 'defined' : 'undefined'} but got ${hasResponse ? 'defined' : 'undefined'}`,\n );\n }\n }\n\n if (expected.hasOpenAPI !== undefined) {\n const hasOpenAPI = !!route.openapi;\n if (hasOpenAPI !== expected.hasOpenAPI) {\n throw new Error(\n `Expected openapi to be ${expected.hasOpenAPI ? 'defined' : 'undefined'} but got ${hasOpenAPI ? 'defined' : 'undefined'}`,\n );\n }\n }\n}\n","import type { ServerRoute } from '@mastra/server/server-adapter';\nimport { describe, it, expect } from 'vitest';\nimport {\n expectInvalidSchema,\n expectValidSchema,\n generateValidDataFromSchema,\n getDefaultValidPathParams,\n getDefaultInvalidPathParams,\n getRouteSpecificSchemaDefaults,\n validateRouteMetadata,\n} from './route-test-utils';\n\n/**\n * Configuration for route test suite\n */\nexport interface RouteTestConfig {\n /** Array of routes to test */\n routes: readonly ServerRoute[];\n}\n\n/**\n * Creates a standardized test suite for server adapter routes\n * Similar to stores/_test-utils pattern\n */\nexport function createRouteTestSuite(config: RouteTestConfig) {\n const { routes } = config;\n\n describe('Route Registration and Metadata', () => {\n it(`should have all ${routes.length} routes registered`, () => {\n expect(routes).toHaveLength(routes.length);\n });\n\n it('should have unique paths for each method', () => {\n const pathMethods = routes.map(r => `${r.method}:${r.path}`);\n const uniquePathMethods = new Set(pathMethods);\n expect(pathMethods.length).toBe(uniquePathMethods.size);\n });\n\n it('should have OpenAPI specs for all routes', () => {\n routes.forEach(route => {\n // Skip 'ALL' method routes - they can't have OpenAPI specs (no standard HTTP method mapping)\n // MCP transport routes use 'ALL' and are tested separately via mcp-transport-test-suite\n if (route.method === 'ALL') {\n return;\n }\n expect(route.openapi).toBeDefined();\n expect(route.openapi?.summary).toBeDefined();\n expect(route.openapi?.description).toBeDefined();\n });\n });\n });\n\n // Test each route\n routes.forEach(route => {\n const routeKey = `${route.method} ${route.path}`;\n\n describe(routeKey, () => {\n // Skip deprecated routes - they are placeholders for route parity only\n if (route.deprecated) {\n it('should be marked as deprecated', () => {\n expect(route.deprecated).toBe(true);\n expect(route.openapi?.deprecated).toBe(true);\n });\n return;\n }\n\n // Route configuration test\n it('should have correct route configuration', () => {\n expect(route).toBeDefined();\n validateRouteMetadata(route, {\n method: route.method,\n path: route.path,\n responseType: route.responseType,\n hasPathParams: !!route.pathParamSchema,\n hasQueryParams: !!route.queryParamSchema,\n hasBody: !!route.bodySchema,\n hasResponse: !!route.responseSchema,\n });\n });\n\n // Schema validation tests - always run\n // Path parameter validation\n if (route.pathParamSchema) {\n it('should validate path parameters', () => {\n const validParams = getDefaultValidPathParams(route);\n const invalidParams = getDefaultInvalidPathParams(route);\n\n expectValidSchema(route.pathParamSchema!, validParams);\n invalidParams.forEach((invalid: any) => {\n expectInvalidSchema(route.pathParamSchema!, invalid);\n });\n });\n }\n\n // Query parameter validation\n if (route.queryParamSchema) {\n it('should validate query parameters', () => {\n const routeDefaults = getRouteSpecificSchemaDefaults(route);\n const generated = generateValidDataFromSchema(route.queryParamSchema!);\n const validParams = { ...generated, ...(routeDefaults.query ?? {}) };\n expectValidSchema(route.queryParamSchema!, validParams);\n });\n }\n\n // Body validation\n if (route.bodySchema) {\n it('should validate request body schema', () => {\n const routeDefaults = getRouteSpecificSchemaDefaults(route);\n const generated = generateValidDataFromSchema(route.bodySchema!);\n const validBody = { ...generated, ...(routeDefaults.body ?? {}) };\n expectValidSchema(route.bodySchema!, validBody);\n });\n }\n\n // Response schema requirement for JSON endpoints\n if (route.responseType === 'json') {\n it('should have response schema defined for JSON endpoint', () => {\n if (!route.responseSchema) {\n throw new Error(\n `${route.method} ${route.path} is missing responseSchema. Add a Zod schema to ensure type safety and API documentation.`,\n );\n }\n });\n }\n });\n });\n}\n","import { randomUUID } from 'node:crypto';\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { Mastra } from '@mastra/core';\nimport { Agent, createMessageSignal, createSignal } from '@mastra/core/agent';\nimport { createScorer } from '@mastra/core/evals';\nimport { LogLevel } from '@mastra/core/logger';\nimport type { BaseLogMessage, IMastraLogger } from '@mastra/core/logger';\nimport { MockMemory } from '@mastra/core/memory';\nimport { SpanType } from '@mastra/core/observability';\nimport type { Processor, ProcessInputArgs, ProcessInputResult } from '@mastra/core/processors';\nimport { InMemoryStore } from '@mastra/core/storage';\nimport type { MemoryStorage } from '@mastra/core/storage';\nimport { UnknownToolProviderError } from '@mastra/core/tool-provider';\nimport { createTool } from '@mastra/core/tools';\nimport type { Tool } from '@mastra/core/tools';\nimport { getZodDef, getZodTypeName } from '@mastra/core/utils';\nimport { MastraVector } from '@mastra/core/vector';\nimport { CompositeVoice } from '@mastra/core/voice';\nimport type { Workflow } from '@mastra/core/workflows';\nimport { createWorkflow, createStep } from '@mastra/core/workflows';\nimport { Workspace, LocalFilesystem } from '@mastra/core/workspace';\nimport { MCPServer } from '@mastra/mcp';\nimport type { InMemoryTaskStore } from '@mastra/server/a2a/store';\nimport { WorkflowRegistry } from '@mastra/server/server-adapter';\nimport type { ServerRoute } from '@mastra/server/server-adapter';\nimport { expect, vi } from 'vitest';\nimport type { Mock } from 'vitest';\nimport * as zod from 'zod';\nimport type { ZodTypeAny } from 'zod';\nimport {\n generateValidDataFromSchema,\n getDefaultValidPathParams,\n getRouteSpecificSchemaDefaults,\n normalizeRoutePath,\n} from './route-test-utils';\nif (process.env.VITEST) {\n vi.mock('@mastra/core/vector');\n\n vi.mock('zod', async importOriginal => {\n const actual: {} = await importOriginal();\n return {\n ...actual,\n };\n });\n}\n\nconst z: any = zod;\n\n/**\n * Test context for adapter integration tests\n * Convention: Create entities with IDs that match auto-generated values:\n * - agentId: 'test-agent'\n * - workflowId: 'test-workflow'\n * - toolId: 'test-tool'\n * - etc.\n */\nexport interface AdapterTestContext {\n mastra: Mastra;\n tools?: Record<string, Tool>;\n taskStore?: InMemoryTaskStore;\n customRouteAuthConfig?: Map<string, boolean>;\n}\n\n/**\n * HTTP request to execute through adapter\n */\nexport interface HttpRequest {\n method: string;\n path: string;\n query?: Record<string, string | string[]>;\n body?: unknown;\n headers?: Record<string, string>;\n}\n\n/**\n * HTTP response from adapter\n */\nexport interface HttpResponse {\n status: number;\n type: 'json' | 'stream';\n data?: unknown;\n stream?: ReadableStream | AsyncIterable<unknown>;\n headers: Record<string, string>;\n}\n\n/**\n * Options for adapter setup\n */\nexport interface AdapterSetupOptions {\n /** Route prefix (e.g., '/v2' or '/api/v2') */\n prefix?: string;\n}\n\n/**\n * Configuration for adapter integration test suite\n */\nexport interface AdapterTestSuiteConfig {\n /** Name for the test suite */\n suiteName?: string;\n\n /** Values produced by the configured framework parser for an omitted body. */\n emptyBodyNormalization?: {\n withoutContentType: 'undefined' | 'empty-object' | 'empty-string';\n withJsonContentType: 'undefined' | 'empty-object' | 'empty-string';\n };\n\n /** Whether the adapter decodes requestContext from POST query parameters. */\n supportsPostQueryRequestContext?: boolean;\n\n /**\n * Setup adapter and app for testing\n * Called once before all tests\n * @param context - Test context with Mastra instance\n * @param options - Optional adapter options (e.g., prefix)\n */\n setupAdapter: (\n context: AdapterTestContext,\n options?: AdapterSetupOptions,\n ) => { adapter: any; app: any } | Promise<{ adapter: any; app: any }>;\n\n /**\n * Execute HTTP request through the adapter's framework (Express/Hono)\n */\n executeHttpRequest: (app: any, request: HttpRequest) => Promise<HttpResponse>;\n\n /**\n * Create test context with Mastra instance, agents, etc.\n * Convention: Create entities with IDs matching auto-generated values\n * Optional - uses createDefaultTestContext() if not provided\n */\n createTestContext?: () => Promise<AdapterTestContext> | AdapterTestContext;\n}\n\n/**\n * Creates a test agent with all common mocks configured\n */\nexport function createTestAgent(\n overrides: {\n id?: string;\n name?: string;\n description?: string;\n instructions?: string;\n tools?: Record<string, any>;\n voice?: CompositeVoice;\n memory?: MockMemory;\n model?: any;\n } = {},\n) {\n const testTool = createTestTool();\n const mockVoice = createMockVoice();\n const mockMemory = createMockMemory();\n\n const agent = new Agent({\n id: overrides.id || 'test-agent',\n name: overrides.name || 'test-agent',\n description: overrides.description || 'A test agent',\n instructions: overrides.instructions || 'Test instructions',\n model: overrides.model || 'openai/gpt-4o',\n tools: overrides.tools || { 'test-tool': testTool },\n voice: overrides.voice || mockVoice,\n memory: overrides.memory || mockMemory,\n });\n\n return agent;\n}\n\n/**\n * Creates a mock vector for testing (following handler test pattern)\n */\nexport function createMockVector() {\n // @ts-expect-error - Mocking for tests\n const mockVector: MastraVector = new MastraVector();\n mockVector.upsert = vi.fn().mockResolvedValue(['id1', 'id2']);\n mockVector.createIndex = vi.fn().mockResolvedValue(undefined);\n mockVector.query = vi.fn().mockResolvedValue([{ id: '1', score: 0.9, vector: [1, 2, 3] }]);\n mockVector.listIndexes = vi.fn().mockResolvedValue(['test-index']);\n mockVector.describeIndex = vi.fn().mockResolvedValue({ dimension: 3, count: 100, metric: 'cosine' });\n mockVector.deleteIndex = vi.fn().mockResolvedValue(undefined);\n\n return mockVector;\n}\n\nexport function mockAgentMethods(agent: Agent) {\n // Mock agent methods that would normally require API calls\n vi.spyOn(agent, 'generate').mockResolvedValue({ text: 'test response' } as any);\n\n // Create a reusable mock stream that returns a proper ReadableStream\n const createMockStream = () => {\n return new ReadableStream({\n start(controller) {\n controller.enqueue({ type: 'text-delta', textDelta: 'test' });\n controller.close();\n },\n });\n };\n\n // Mock stream method - returns object with fullStream property\n vi.spyOn(agent, 'stream').mockResolvedValue({ fullStream: createMockStream() } as any);\n\n // Mock resumeStream method - returns object with fullStream property\n vi.spyOn(agent, 'resumeStream').mockResolvedValue({ fullStream: createMockStream() } as any);\n\n // Mock legacy generate - returns GenerateTextResult (JSON object, not stream)\n vi.spyOn(agent, 'generateLegacy').mockResolvedValue({\n text: 'test response',\n toolCalls: [],\n finishReason: 'stop',\n usage: { promptTokens: 10, completionTokens: 5 },\n experimental_output: undefined,\n response: {\n id: 'test-response-id',\n timestamp: new Date(),\n modelId: 'gpt-4',\n },\n request: {},\n warnings: [],\n } as any);\n\n // Helper to create a mock Response object for datastream-response routes\n const createMockResponse = () => {\n const stream = createMockStream();\n return new Response(stream, {\n status: 200,\n headers: {\n 'Content-Type': 'text/plain; charset=utf-8',\n 'Transfer-Encoding': 'chunked',\n },\n });\n };\n\n // Mock streamLegacy - needs to return an object with toDataStreamResponse/toTextStreamResponse methods\n const mockStreamResult = {\n ...createMockStream(),\n toDataStreamResponse: vi.fn().mockImplementation(() => createMockResponse()),\n toTextStreamResponse: vi.fn().mockImplementation(() => createMockResponse()),\n };\n vi.spyOn(agent, 'streamLegacy').mockResolvedValue(mockStreamResult as any);\n\n // Mock approveToolCall method - returns object with fullStream property\n vi.spyOn(agent, 'approveToolCall').mockResolvedValue({ fullStream: createMockStream() } as any);\n\n // Mock declineToolCall method - returns object with fullStream property\n vi.spyOn(agent, 'declineToolCall').mockResolvedValue({ fullStream: createMockStream() } as any);\n\n // Mock approveToolCallGenerate method - returns same format as generate\n vi.spyOn(agent, 'approveToolCallGenerate').mockResolvedValue({ text: 'test response' } as any);\n\n // Mock declineToolCallGenerate method - returns same format as generate\n vi.spyOn(agent, 'declineToolCallGenerate').mockResolvedValue({ text: 'test response' } as any);\n\n vi.spyOn(agent, 'sendToolApproval').mockResolvedValue({\n accepted: true,\n runId: 'test-run',\n toolCallId: 'test-tool',\n } as any);\n\n // Mock network method\n vi.spyOn(agent, 'network').mockResolvedValue(createMockStream() as any);\n\n vi.spyOn(agent, 'sendSignal').mockImplementation((signal: any, target: any) => {\n const createdSignal = createSignal(signal);\n const runId = target?.runId ?? 'test-run';\n return {\n accepted: Promise.resolve({ action: 'deliver', runId }),\n signal: createdSignal,\n } as any;\n });\n\n vi.spyOn(agent, 'sendMessage').mockImplementation((message: any, target: any) => {\n const createdSignal = createMessageSignal(message);\n const runId = target?.runId ?? 'test-run';\n return {\n accepted: Promise.resolve({ action: 'deliver', runId }),\n signal: createdSignal,\n } as any;\n });\n\n vi.spyOn(agent, 'queueMessage').mockImplementation((message: any, target: any) => {\n const createdSignal = createMessageSignal(message);\n const runId = target?.runId ?? 'test-run';\n return {\n accepted: Promise.resolve({ action: 'deliver', runId }),\n signal: createdSignal,\n } as any;\n });\n\n vi.spyOn(agent, 'queueSignal').mockImplementation((signal: any, target: any) => {\n const createdSignal = createSignal(signal);\n const runId = target?.runId ?? 'test-run';\n return {\n accepted: Promise.resolve({ action: 'deliver', runId }),\n signal: createdSignal,\n } as any;\n });\n\n vi.spyOn(agent, 'subscribeToThread').mockResolvedValue({\n stream: (async function* () {\n yield { type: 'text-delta', textDelta: 'test' };\n })(),\n activeRunId: () => 'test-run',\n abort: vi.fn(() => true),\n unsubscribe: vi.fn(),\n } as any);\n\n // Mock getVoice to return the voice object that the handler expects\n const mockVoice = createMockVoice();\n\n // Mock voice methods to avoid \"No listener/speaker provider configured\" errors\n vi.spyOn(mockVoice, 'getSpeakers').mockResolvedValue([]);\n vi.spyOn(mockVoice, 'getListener').mockResolvedValue({ enabled: false } as any);\n vi.spyOn(mockVoice, 'speak').mockResolvedValue(\n new ReadableStream({\n start(controller) {\n controller.enqueue(new TextEncoder().encode('mock audio data'));\n controller.close();\n },\n }) as any,\n );\n vi.spyOn(mockVoice, 'listen').mockResolvedValue('transcribed text');\n\n vi.spyOn(agent, 'getVoice').mockResolvedValue(mockVoice);\n\n // Mock model list methods with proper model data structure\n vi.spyOn(agent, 'getModelList').mockResolvedValue([\n {\n id: 'id1',\n enabled: true,\n maxRetries: 3,\n modelId: 'gpt-4o',\n provider: 'openai',\n model: {\n modelId: 'gpt-4o',\n provider: 'openai',\n specificationVersion: 'v1',\n },\n },\n {\n id: 'id2',\n enabled: true,\n maxRetries: 3,\n modelId: 'gpt-4o-mini',\n provider: 'openai',\n model: {\n modelId: 'gpt-4o-mini',\n provider: 'openai',\n specificationVersion: 'v1',\n },\n },\n ] as any);\n\n return agent;\n}\n\n// Mock legacy workflow stream methods\nconst createMockWorkflowStream = () => {\n return new ReadableStream({\n start(controller) {\n controller.enqueue(new TextEncoder().encode('data: {\"type\":\"step-result\",\"result\":\"test\"}\\n\\n'));\n controller.close();\n },\n });\n};\n\n/**\n * Create a default test context with mocked Mastra instance, agents, workflows, etc.\n * This provides everything needed for adapter integration tests.\n */\nexport async function createDefaultTestContext(): Promise<AdapterTestContext> {\n // Mock OPENAI_API_KEY so that isProviderConnected('openai') returns true\n // This is needed for routes like ENHANCE_INSTRUCTIONS_ROUTE that check provider connectivity\n vi.stubEnv('OPENAI_API_KEY', 'test-api-key');\n\n // Create memory and pre-populate with test thread\n const memory = createMockMemory();\n await memory.createThread({\n threadId: 'test-thread',\n resourceId: 'test-resource',\n metadata: {},\n });\n\n // Create vector instance\n const vector = createMockVector();\n\n // Create test tool\n const testTool = createTestTool({ id: 'test-tool' });\n\n // Create test agent with memory and mocks\n const agent = createTestAgent({\n name: 'test-agent',\n memory,\n model: [\n { id: 'id1', model: 'openai/gpt-4o', maxRetries: 3 },\n { id: 'id2', model: 'openai/gpt-4o-mini', maxRetries: 3 },\n ],\n });\n mockAgentMethods(agent);\n\n // Mock Agent.prototype.generate for routes that create new Agent instances\n // (e.g., ENHANCE_INSTRUCTIONS_ROUTE creates a systemPromptAgent)\n // This needs to return both text and object for different use cases\n vi.spyOn(Agent.prototype, 'generate').mockResolvedValue({\n text: 'test response',\n object: {\n explanation: 'Enhanced the instructions for clarity and specificity.',\n new_prompt: 'You are a helpful assistant with enhanced instructions.',\n },\n } as any);\n\n // Create test workflow with mocks\n const workflow = createTestWorkflow({ id: 'test-workflow' });\n const mergeTemplateWorkflow = createTestWorkflow({ id: 'merge-template' });\n const workflowBuilderWorkflow = createTestWorkflow({ id: 'workflow-builder' });\n\n // Create test scorer\n const testScorer = createScorer({\n id: 'test-scorer',\n name: 'Test Scorer',\n description: 'Test scorer for observability tests',\n });\n\n // Create test processor\n const testProcessor = createTestProcessor({ id: 'test-processor' });\n\n mockLogger.transports = new Map([\n ['console', {}],\n ['file', {}],\n ]) as unknown as Record<string, unknown>;\n\n const mockLogs: BaseLogMessage[] = [createLog({})];\n\n mockLogger.listLogsByRunId.mockResolvedValue({\n logs: mockLogs,\n total: 1,\n page: 1,\n perPage: 100,\n hasMore: false,\n });\n\n mockLogger.listLogs.mockResolvedValue({ logs: mockLogs, total: 1, page: 1, perPage: 100, hasMore: false });\n\n const weatherTool = createTool({\n id: 'getWeather',\n description: 'Gets the current weather for a location',\n inputSchema: zod.z.object({\n location: zod.z.string().describe('The location to get weather for'),\n }),\n outputSchema: zod.z.object({\n temperature: zod.z.number(),\n condition: zod.z.string(),\n }),\n execute: async ({ location }) => ({\n temperature: 72,\n condition: `Sunny in ${location}`,\n }),\n });\n\n const calculatorTool = createTool({\n id: 'calculate',\n description: 'Performs basic calculations',\n inputSchema: zod.z.object({\n operation: zod.z.enum(['add', 'subtract', 'multiply', 'divide']),\n a: zod.z.number(),\n b: zod.z.number(),\n }),\n outputSchema: zod.z.object({\n result: zod.z.number(),\n }),\n execute: async ({ operation, a, b }) => {\n let result = 0;\n switch (operation) {\n case 'add':\n result = a + b;\n break;\n case 'subtract':\n result = a - b;\n break;\n case 'multiply':\n result = a * b;\n break;\n case 'divide':\n result = b !== 0 ? a / b : Infinity;\n break;\n }\n return { result };\n },\n });\n\n const failingTool = createTool({\n id: 'failingTool',\n description: 'A tool that always throws an error for testing error handling',\n inputSchema: z.object({}),\n outputSchema: z.object({}),\n execute: async () => {\n throw new Error('Tool execution failed intentionally');\n },\n });\n\n // Create real MCP servers with tools and app resources\n const mcpServer1 = new MCPServer({\n name: 'Test Server 1',\n version: '1.0.0',\n description: 'Test MCP Server 1',\n tools: {\n getWeather: weatherTool,\n calculate: calculatorTool,\n },\n appResources: {\n 'ui://test/app': {\n name: 'Test App',\n html: '<html><body>Test</body></html>',\n },\n },\n });\n\n const mcpServer2 = new MCPServer({\n name: 'Test Server 2',\n version: '1.1.0',\n description: 'Test MCP Server 2',\n tools: {\n failingTool: failingTool,\n },\n appResources: {\n 'ui://test/app2': {\n name: 'Test App 2',\n html: '<html><body>Test 2</body></html>',\n },\n },\n });\n\n // Create test workspace with local filesystem and mock files\n const workspace = await createTestWorkspace();\n\n // Create Mastra instance with all test entities\n // Mock channel provider for channel route tests\n const mockChannelProvider = {\n id: 'test-platform',\n getRoutes: () => [],\n getInfo: () => ({\n id: 'test-platform',\n name: 'Test Platform',\n isConfigured: true,\n }),\n connect: async () => ({\n type: 'immediate' as const,\n installationId: 'test-installation',\n }),\n disconnect: async () => {},\n listInstallations: async () => [\n {\n id: 'test-installation',\n platform: 'test-platform',\n agentId: 'test-agent',\n status: 'active' as const,\n displayName: 'Test Installation',\n installedAt: new Date(),\n },\n ],\n };\n\n const mastra = new Mastra({\n logger: mockLogger as unknown as IMastraLogger,\n storage: new InMemoryStore(),\n agents: {\n 'test-agent': agent,\n },\n workflows: {\n 'test-workflow': workflow,\n },\n scorers: { 'test-scorer': testScorer },\n vectors: { 'test-vector': vector },\n mcpServers: {\n 'test-server-1': mcpServer1,\n 'test-server-2': mcpServer2,\n },\n workspace,\n processors: {\n 'test-processor': testProcessor,\n },\n backgroundTasks: {\n enabled: true,\n },\n channels: {\n 'test-platform': mockChannelProvider as any,\n },\n });\n\n // Mock getEditor to return an object with namespaced methods for stored agents routes\n const mockToolProvider = {\n info: { id: 'test-provider', name: 'Test Provider', description: 'A test tool provider' },\n listToolkits: vi.fn().mockResolvedValue({ data: [] }),\n listTools: vi.fn().mockResolvedValue({ data: [], total: 0, page: 0, perPage: 20, hasMore: false }),\n getToolSchema: vi.fn().mockResolvedValue({ name: 'test-tool-slug', inputSchema: {}, outputSchema: {} }),\n };\n const mockProcessorProvider = {\n info: { id: 'test-provider', name: 'Test Processor Provider', description: 'A test processor provider' },\n configSchema: z.object({}),\n availablePhases: ['processInput'] as const,\n createProcessor: vi.fn(),\n };\n vi.spyOn(mastra, 'getEditor').mockReturnValue({\n hasEnabledBuilderConfig: () => true,\n resolveBuilder: async () => ({\n enabled: true,\n getFeatures: () => ({ agent: { favorites: true } }),\n getConfiguration: () => undefined,\n getModelPolicyWarnings: () => [],\n }),\n hasEnabledWorkflowBuilderConfig: () => true,\n resolveWorkflowBuilder: async () => ({\n enabled: true,\n getAgent: () => agent,\n getModelPolicy: () => undefined,\n }),\n prompt: {\n preview: vi.fn().mockResolvedValue('resolved instructions preview'),\n clearCache: vi.fn(),\n },\n mcp: {\n clearCache: vi.fn(),\n },\n agent: {\n list: vi.fn().mockResolvedValue({ agents: [] }),\n clearCache: vi.fn(),\n create: vi.fn().mockImplementation(async (input: any) => {\n // Delegate to storage directly, mirroring what editor.agent.create does\n const agents = await mastra.getStorage()!.getStore('agents');\n return agents!.create({ agent: input });\n }),\n clone: vi.fn().mockResolvedValue({\n id: 'cloned-agent',\n name: 'Test Agent (Clone)',\n status: 'draft',\n description: '',\n instructions: 'test instructions',\n model: { provider: 'openai', name: 'gpt-4o' },\n createdAt: new Date(),\n updatedAt: new Date(),\n }),\n },\n scorer: {\n clearCache: vi.fn(),\n },\n getToolProviders: vi.fn().mockReturnValue({ 'test-provider': mockToolProvider }),\n getToolProvider: vi\n .fn()\n .mockImplementation((id: string) => (id === 'test-provider' ? mockToolProvider : undefined)),\n getToolProviderOrThrow: vi.fn().mockImplementation((id: string) => {\n if (id === 'test-provider') return mockToolProvider;\n throw new UnknownToolProviderError(id, ['test-provider']);\n }),\n getProcessorProviders: vi.fn().mockReturnValue({ 'test-provider': mockProcessorProvider }),\n getProcessorProvider: vi\n .fn()\n .mockImplementation((id: string) => (id === 'test-provider' ? mockProcessorProvider : undefined)),\n } as any);\n\n await mockWorkflowRun(workflow);\n await setupWorkflowRegistryMocks(\n {\n 'merge-template': mergeTemplateWorkflow,\n 'workflow-builder': workflowBuilderWorkflow,\n },\n mastra,\n );\n\n // Add test trace by creating a span with that traceId\n const storage = mastra.getStorage();\n if (storage) {\n const observability = await storage.getStore('observability');\n if (observability) {\n vi.spyOn(observability, 'getFeatures').mockReturnValue([\n ...(observability.getFeatures() ?? []),\n 'trace-query',\n 'trace-query-discovery',\n 'trace-aggregate',\n 'thread-query',\n 'thread-query-rows',\n 'span-query',\n ]);\n vi.spyOn(observability, 'queryTraces').mockResolvedValue({ traces: [], page: { next: null } });\n vi.spyOn(observability, 'aggregateTraces').mockResolvedValue({ rows: [], truncated: false });\n vi.spyOn(observability, 'getTraceQueryObservedFields').mockResolvedValue({\n observedFields: [],\n observedFieldsTruncated: false,\n });\n vi.spyOn(observability, 'getTraceQueryValues').mockResolvedValue({ values: [], valuesTruncated: false });\n vi.spyOn(observability, 'queryThreads').mockResolvedValue({ threads: [], page: { next: null } });\n vi.spyOn(observability, 'querySpans').mockResolvedValue({ spans: [], page: { next: null } });\n await observability.createSpan({\n span: {\n spanId: 'test-span',\n traceId: 'test-trace',\n name: 'test-span',\n spanType: SpanType.GENERIC,\n startedAt: new Date(),\n endedAt: new Date(),\n isEvent: false,\n },\n });\n\n // Add test feedback for the review-status route\n await observability.createFeedback({\n feedback: {\n feedbackId: 'test-feedback',\n timestamp: new Date(),\n traceId: 'test-trace',\n spanId: 'test-span',\n feedbackSource: 'user',\n feedbackType: 'comment',\n value: 'test feedback',\n reviewStatus: 'needs-review',\n },\n });\n }\n\n // Add test stored agent for stored agents routes\n const agents = await storage.getStore('agents');\n if (agents) {\n // create automatically creates version 1 with the initial config\n const storedAgent = await agents.create({\n agent: {\n id: 'test-stored-agent',\n name: 'Test Stored Agent',\n description: 'A test stored agent for integration tests',\n instructions: 'Test instructions for stored agent',\n model: { provider: 'openai', name: 'gpt-4o' },\n },\n });\n\n // Version 1 was auto-created by create; its ID is the activeVersionId\n const version1Id = storedAgent.activeVersionId!;\n\n // Version 2: Non-active version that can be deleted or used in comparisons\n // Config fields are top-level (no snapshot object)\n await agents.createVersion({\n id: 'test-version-id',\n agentId: 'test-stored-agent',\n versionNumber: 2,\n name: 'Test Stored Agent',\n instructions: 'Updated test instructions for version 2',\n model: { provider: 'openai', name: 'gpt-4o' },\n changedFields: ['instructions'],\n changeMessage: 'Second test version',\n });\n\n // Ensure version 1 stays active, leaving version 2 (test-version-id) as non-active and deletable\n await agents.update({\n id: 'test-stored-agent',\n activeVersionId: version1Id,\n });\n }\n\n // Add test stored scorer for stored scorers routes\n const scorers = await storage.getStore('scorerDefinitions');\n if (scorers) {\n const storedScorer = await scorers.create({\n scorerDefinition: {\n id: 'test-stored-scorer',\n name: 'Test Stored Scorer',\n description: 'A test stored scorer for integration tests',\n type: 'llm-judge',\n instructions: 'Evaluate the response for accuracy.',\n model: { provider: 'openai', name: 'gpt-4o' },\n scoreRange: { min: 0, max: 1 },\n },\n });\n // Version 2 with known ID for version-specific route tests\n await scorers.createVersion({\n id: 'test-version-id',\n scorerDefinitionId: 'test-stored-scorer',\n versionNumber: 2,\n name: 'Test Stored Scorer',\n type: 'llm-judge',\n instructions: 'Updated instructions for version 2.',\n model: { provider: 'openai', name: 'gpt-4o' },\n scoreRange: { min: 0, max: 1 },\n changedFields: ['instructions'],\n changeMessage: 'Second test version',\n });\n }\n\n // Add test stored MCP client with version 2 (version 1 is auto-created by create())\n const mcpClients = await storage.getStore('mcpClients');\n if (mcpClients) {\n await mcpClients.create({\n mcpClient: {\n id: 'test-stored-mcp-client',\n name: 'Test Stored MCP Client',\n servers: { 'test-server': { type: 'http', url: 'http://localhost:3000' } },\n },\n });\n await mcpClients.createVersion({\n id: 'test-version-id',\n mcpClientId: 'test-stored-mcp-client',\n versionNumber: 2,\n name: 'Test Stored MCP Client',\n servers: { 'test-server': { type: 'http', url: 'http://localhost:3001' } },\n changedFields: ['servers'],\n changeMessage: 'Second test version',\n });\n }\n\n // Add test stored prompt block with version 2\n const promptBlocks = await storage.getStore('promptBlocks');\n if (promptBlocks) {\n await promptBlocks.create({\n promptBlock: {\n id: 'test-stored-prompt-block',\n name: 'Test Stored Prompt Block',\n content: 'Hello {{name}}, this is a test prompt block.',\n },\n });\n await promptBlocks.createVersion({\n id: 'test-version-id',\n blockId: 'test-stored-prompt-block',\n versionNumber: 2,\n name: 'Test Stored Prompt Block',\n content: 'Updated content for {{name}}.',\n changedFields: ['content'],\n changeMessage: 'Second test version',\n });\n }\n\n // Add test stored workspace and skill (no extra versions needed)\n const workspaces = await storage.getStore('workspaces');\n if (workspaces) {\n await workspaces.create({\n workspace: { id: 'test-stored-workspace', name: 'Test Stored Workspace' },\n });\n }\n const skills = await storage.getStore('skills');\n if (skills) {\n await skills.create({\n skill: {\n id: 'test-stored-skill',\n name: 'test-stored-skill',\n description: 'A test stored skill',\n instructions: 'Test skill instructions',\n },\n });\n }\n\n // Add test dynamic workflow definition so GET /stored/workflows/:dynamicWorkflowId\n // finds a row matching getDefaultValidPathParams' 'test-dynamic-workflow'\n const workflowDefinitions = await storage.getStore('workflowDefinitions');\n if (workflowDefinitions) {\n await workflowDefinitions.upsert({\n id: 'test-dynamic-workflow',\n description: 'Test dynamic workflow',\n inputSchema: { type: 'object', properties: { name: { type: 'string' } }, required: ['name'] },\n outputSchema: { type: 'object', properties: { message: { type: 'string' } } },\n graph: [\n {\n type: 'mapping',\n id: 'greet',\n mapConfig: JSON.stringify({ message: { template: 'Hello, ${initData.name}!' } }),\n },\n ],\n });\n }\n\n const backgroundTasks = await storage.getStore('backgroundTasks');\n if (backgroundTasks) {\n await backgroundTasks.createTask({\n id: 'test-background-task-id',\n status: 'pending',\n toolName: 'test-tool',\n toolCallId: 'test-tool-call-id',\n agentId: 'test-agent',\n runId: 'test-run',\n args: { query: 'test' },\n retryCount: 0,\n maxRetries: 0,\n timeoutMs: 300_000,\n createdAt: new Date(),\n });\n\n await backgroundTasks.updateTask('test-background-task-id', {\n status: 'running',\n startedAt: new Date(),\n });\n }\n\n const schedules = await storage.getStore('schedules');\n if (schedules) {\n const now = Date.now();\n await schedules.createSchedule({\n id: 'test-schedule',\n target: { type: 'workflow', workflowId: 'test-workflow' },\n cron: '* * * * *',\n status: 'active',\n nextFireAt: now + 60_000,\n createdAt: now,\n updatedAt: now,\n });\n await schedules.createSchedule({\n id: 'agent_test-agent-schedule',\n target: { type: 'agent', agentId: 'test-agent', prompt: 'ping' },\n cron: '* * * * *',\n status: 'active',\n nextFireAt: now + 60_000,\n createdAt: now,\n updatedAt: now,\n });\n }\n\n const saveStoredResponseFixtures = async (memoryStore: MemoryStorage | undefined) => {\n if (!memoryStore) {\n return;\n }\n\n await memoryStore.saveThread({\n thread: {\n id: 'test-thread',\n resourceId: 'test-resource',\n createdAt: new Date(),\n updatedAt: new Date(),\n metadata: {},\n },\n });\n await memoryStore.saveMessages({\n messages: [\n {\n id: 'test-message-1',\n threadId: 'test-thread',\n role: 'user',\n content: {\n format: 2,\n parts: [{ type: 'text', text: 'Test message' }],\n },\n createdAt: new Date(),\n },\n {\n id: 'test-response',\n threadId: 'test-thread',\n resourceId: 'test-resource',\n role: 'assistant',\n type: 'text',\n content: {\n format: 2,\n parts: [{ type: 'text', text: 'Test stored response' }],\n metadata: {\n mastra: {\n response: {\n agentId: 'test-agent',\n model: 'openai/gpt-4o',\n createdAt: Math.floor(Date.now() / 1000),\n completedAt: Math.floor(Date.now() / 1000),\n status: 'completed',\n usage: null,\n tools: [],\n store: true,\n messageIds: ['test-message-1', 'test-response'],\n },\n },\n },\n },\n createdAt: new Date(),\n },\n ],\n });\n };\n\n // Seed the root memory store for routes that resolve memory directly from Mastra storage.\n await saveStoredResponseFixtures(await storage.getStore('memory'));\n\n // Seed the agent memory store for Responses routes that now resolve stored responses\n // through agent memory first and only inherit root storage via the agent-memory path.\n await saveStoredResponseFixtures(await memory.storage.getStore('memory'));\n }\n\n return {\n mastra,\n tools: { 'test-tool': testTool },\n };\n}\n\nasync function mockWorkflowRun(workflow: Workflow<any, any, any, any, any, any, any, any>) {\n // Mock getWorkflowRunById to return a mock WorkflowState object\n // This is the unified format that includes both metadata and processed execution state\n // Only 'test-run' exists; unknown runIds resolve to null so stream routes can\n // start fresh runs without tripping the terminal-run 409 guard.\n vi.spyOn(workflow, 'getWorkflowRunById').mockImplementation(async (runId: string) =>\n runId !== 'test-run'\n ? (null as any)\n : ({\n runId: 'test-run',\n workflowName: 'test-workflow',\n resourceId: 'test-resource',\n createdAt: new Date(),\n updatedAt: new Date(),\n status: 'success',\n result: { output: 'test-output' },\n payload: {},\n steps: {\n step1: {\n status: 'success',\n output: { result: 'test-output' },\n startedAt: Date.now() - 1000,\n endedAt: Date.now(),\n },\n },\n activeStepsPath: {},\n serializedStepGraph: [{ type: 'step', step: { id: 'step1' } }],\n } as any),\n );\n\n // Mock createRun to return a mocked run object with all required methods\n const originalCreateRun = workflow.createRun.bind(workflow);\n vi.spyOn(workflow, 'createRun').mockImplementation(async (options?: any) => {\n const run = await originalCreateRun(options);\n\n // Mock stream methods\n vi.spyOn(run, 'streamLegacy').mockReturnValue({\n stream: createMockWorkflowStream(),\n } as any);\n vi.spyOn(run, 'observeStreamLegacy').mockReturnValue({\n stream: createMockWorkflowStream(),\n } as any);\n\n // Mock start to return a successful result\n vi.spyOn(run, 'start').mockResolvedValue({\n results: {},\n status: 'success',\n } as any);\n\n // Mock restart to return a successful result\n vi.spyOn(run, 'restart').mockResolvedValue({\n results: {},\n status: 'success',\n } as any);\n\n // Mock resume to return a successful result\n vi.spyOn(run, 'resume').mockResolvedValue({\n results: {},\n status: 'success',\n } as any);\n\n // Mock timeTravel to return a successful result\n vi.spyOn(run, 'timeTravel').mockResolvedValue({\n results: {},\n status: 'success',\n } as any);\n\n return run;\n });\n}\n\n/**\n * Creates a mock voice provider\n */\nexport function createMockVoice() {\n return new CompositeVoice({});\n}\n\n/**\n * Creates a test workspace with a local filesystem and mock skill files.\n * Uses a temporary directory that gets cleaned up after tests.\n */\nexport async function createTestWorkspace(): Promise<Workspace> {\n // Create a temp directory for the test workspace\n const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mastra-test-workspace-'));\n\n // Create skills directory and a test skill\n const skillsDir = path.join(tempDir, 'skills', 'test-skill');\n fs.mkdirSync(skillsDir, { recursive: true });\n\n // Create SKILL.md file for the test skill\n const skillContent = `---\nname: test-skill\ndescription: A test skill for integration testing\nlicense: MIT\ncompatibility: \">=1.0.0\"\n---\n\n# Test Skill\n\nThis is a test skill used for integration testing.\n\n## Instructions\n\nFollow these instructions for the test skill.\n`;\n fs.writeFileSync(path.join(skillsDir, 'SKILL.md'), skillContent);\n\n // Create a test reference file in the references subdirectory\n const referencesDir = path.join(skillsDir, 'references');\n fs.mkdirSync(referencesDir, { recursive: true });\n fs.writeFileSync(path.join(referencesDir, 'test-reference.md'), '# Test Reference\\n\\nThis is a test reference file.');\n\n // Create a regular test file in the workspace root\n fs.writeFileSync(path.join(tempDir, 'test-file.txt'), 'Hello from test workspace!');\n\n // Create a test directory for list operations\n const testDir = path.join(tempDir, 'test-dir');\n fs.mkdirSync(testDir, { recursive: true });\n fs.writeFileSync(path.join(testDir, 'nested-file.txt'), 'Nested file content');\n\n // Create .agents/skills/ structure for skills-sh routes (remove, check-updates, update)\n const agentSkillsDir = path.join(tempDir, '.agents', 'skills', 'test-skill');\n fs.mkdirSync(agentSkillsDir, { recursive: true });\n fs.writeFileSync(path.join(agentSkillsDir, 'SKILL.md'), skillContent);\n\n // Create .meta.json for the installed skill (used by update routes)\n // Use a fixed timestamp for deterministic tests\n const installedAt = new Date('2024-01-01T00:00:00.000Z').toISOString();\n const metaJson = {\n skillName: 'test-skill',\n owner: 'test-owner',\n repo: 'test-repo',\n branch: 'main',\n installedAt,\n };\n fs.writeFileSync(path.join(agentSkillsDir, '.meta.json'), JSON.stringify(metaJson, null, 2));\n\n // Create the workspace with local filesystem and BM25 search\n // Use 'test-workspace' as the ID to match test utilities' getDefaultValidPathParams\n const filesystem = new LocalFilesystem({ basePath: tempDir });\n const workspace = new Workspace({\n id: 'test-workspace',\n filesystem,\n skills: ['skills'],\n bm25: true, // Enable BM25 search for index/unindex operations\n });\n\n // Initialize the workspace\n await workspace.init();\n\n return workspace;\n}\n\n/**\n * Creates a test tool with basic schema\n */\nexport function createTestTool(\n overrides: {\n id?: string;\n description?: string;\n inputSchema?: ZodTypeAny;\n outputSchema?: ZodTypeAny;\n execute?: (input: any) => Promise<any>;\n } = {},\n) {\n return createTool({\n id: overrides.id || 'test-tool',\n description: overrides.description || 'A test tool',\n inputSchema: overrides.inputSchema || z.object({ key: z.string() }),\n outputSchema: overrides.outputSchema || z.object({ result: z.string() }),\n execute: overrides.execute || (async _inputData => ({ result: 'success' })),\n });\n}\n\n/**\n * Creates a mock memory instance with InMemoryStore\n * Following the pattern from handler tests - uses actual MockMemory implementation\n */\nexport function createMockMemory() {\n const storage = new InMemoryStore();\n const mockMemory = new MockMemory({ storage });\n (mockMemory as any).__registerMastra = vi.fn();\n return mockMemory;\n}\n\n/**\n * Creates a test processor for integration tests\n */\nexport function createTestProcessor(\n overrides: {\n id?: string;\n name?: string;\n description?: string;\n } = {},\n): Processor {\n return {\n id: overrides.id || 'test-processor',\n name: overrides.name || 'Test Processor',\n description: overrides.description || 'A test processor for integration tests',\n async processInput({ messages }: ProcessInputArgs): Promise<ProcessInputResult> {\n // Simple pass-through processor\n return messages;\n },\n };\n}\n\n/**\n * Creates a test workflow with a suspending step\n * Following the pattern from handler tests - always includes suspend for resume tests\n */\nexport function createTestWorkflow(\n overrides: {\n id?: string;\n description?: string;\n } = {},\n) {\n const execute = vi.fn(async (_args: unknown) => ({ result: 'success' }));\n const stepA = createStep({\n id: 'test-step',\n inputSchema: z.object({}),\n outputSchema: z.object({}),\n execute: async ({ suspend }: any) => {\n await suspend({ test: 'data' });\n },\n });\n const stepB = createStep({\n id: 'test-step2',\n inputSchema: z.object({ name: z.string() }),\n outputSchema: z.object({ result: z.string() }),\n execute: async args => execute(args),\n });\n\n return createWorkflow({\n id: overrides.id || 'test-workflow',\n description: overrides.description || 'A test workflow',\n steps: [stepA, stepB],\n inputSchema: z.object({}),\n outputSchema: z.object({ result: z.string() }),\n })\n .then(stepA)\n .then(stepB)\n .commit();\n}\n\n/**\n * Recursively converts ISO date strings to Date objects in response data.\n * This is needed because HTTP responses serialize dates to strings via JSON.stringify(),\n * but schemas expect Date objects for validation.\n *\n * @param data - The response data from HTTP (with dates as ISO strings)\n * @returns The same data with ISO date strings converted to Date objects\n */\n/**\n * Check if a Zod schema expects a Date type at a given path\n */\nfunction schemaExpectsDate(schema: any, path: string[] = []): boolean {\n if (!schema) return false;\n\n let typeName = getZodTypeName(schema);\n let def = getZodDef(schema);\n\n // Unwrap effects, optional, nullable, default to get to the base type\n while (\n typeName === 'ZodEffects' ||\n typeName === 'ZodOptional' ||\n typeName === 'ZodNullable' ||\n typeName === 'ZodDefault'\n ) {\n if (typeName === 'ZodEffects') {\n schema = schema._def.schema;\n } else if (typeName === 'ZodOptional' || typeName === 'ZodNullable') {\n schema = def.innerType;\n } else if (typeName === 'ZodDefault') {\n schema = def.innerType;\n }\n typeName = getZodTypeName(schema);\n def = getZodDef(schema);\n }\n\n typeName = getZodTypeName(schema);\n def = getZodDef(schema);\n\n // If we have a path, navigate to that field\n if (path.length > 0) {\n const [fieldName] = path;\n if (!fieldName) {\n return false;\n }\n if (typeName === 'ZodObject') {\n const shape = typeof def.shape === 'function' ? def.shape() : def.shape;\n const fieldSchema = shape[fieldName];\n return schemaExpectsDate(fieldSchema, path.slice(1));\n } else if (typeName === 'ZodArray') {\n // For arrays, check the element type (ignore the array index in path)\n return schemaExpectsDate(def.element, path.slice(1));\n }\n return false;\n }\n\n // Check if this is a Date type\n return typeName === 'ZodDate';\n}\n\nexport function parseDatesInResponse(data: any, schema?: any, currentPath: string[] = []): any {\n if (data === null || data === undefined) {\n return data;\n }\n\n if (typeof data === 'string') {\n // Only parse dates if the schema expects a Date at this path\n if (schema && schemaExpectsDate(schema, currentPath)) {\n const isoDateRegex = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z?$/;\n if (isoDateRegex.test(data)) {\n const parsed = new Date(data);\n if (!isNaN(parsed.getTime())) {\n return parsed;\n }\n }\n }\n return data;\n }\n\n if (Array.isArray(data)) {\n return data.map((item, index) => parseDatesInResponse(item, schema, [...currentPath, String(index)]));\n }\n\n if (typeof data === 'object') {\n const result: any = {};\n for (const [key, value] of Object.entries(data)) {\n result[key] = parseDatesInResponse(value, schema, [...currentPath, key]);\n }\n return result;\n }\n\n return data;\n}\n\nasync function setupWorkflowRegistryMocks(\n workflows: Record<string, Workflow<any, any, any, any, any, any, any, any>>,\n mastra: Mastra,\n) {\n for (const workflow of Object.values(workflows)) {\n workflow.__registerMastra(mastra);\n workflow.__registerPrimitives({\n logger: mastra.getLogger(),\n storage: mastra.getStorage(),\n agents: mastra.listAgents(),\n tts: mastra.getTTS(),\n vectors: mastra.listVectors(),\n });\n await mockWorkflowRun(workflow);\n }\n\n // Mock WorkflowRegistry.registerTemporaryWorkflows to attach Mastra to workflows\n vi.spyOn(WorkflowRegistry, 'registerTemporaryWorkflows').mockImplementation(() => {\n for (const [id, workflow] of Object.entries(workflows)) {\n // Register Mastra instance with the workflow\n if (mastra) {\n workflow.__registerMastra(mastra);\n workflow.__registerPrimitives({\n logger: mastra.getLogger(),\n storage: mastra.getStorage(),\n agents: mastra.listAgents(),\n tts: mastra.getTTS(),\n vectors: mastra.listVectors(),\n });\n }\n WorkflowRegistry['additionalWorkflows'][id] = workflow;\n }\n });\n}\n\nexport function createLog(args: Partial<BaseLogMessage>): BaseLogMessage {\n return {\n msg: 'test log',\n level: LogLevel.INFO,\n time: new Date(),\n ...args,\n pid: 1,\n hostname: 'test-host',\n name: 'test-name',\n runId: 'test-run',\n };\n}\n\ntype MockedLogger = {\n listLogsByRunId: Mock<IMastraLogger['listLogsByRunId']>;\n listLogs: Mock<IMastraLogger['listLogs']>;\n};\n\nconst mockLogger = {\n listLogsByRunId: vi.fn(),\n listLogs: vi.fn(),\n transports: new Map<string, unknown>(),\n warn: vi.fn(),\n info: vi.fn(),\n debug: vi.fn(),\n error: vi.fn(),\n cleanup: vi.fn(),\n trackException: vi.fn(),\n getTransports: vi.fn(() => mockLogger.transports ?? new Map<string, unknown>()),\n} as unknown as MockedLogger & {\n transports: Record<string, unknown>;\n getTransports: () => Map<string, unknown>;\n};\n\nexport interface RouteRequestPayload {\n method: ServerRoute['method'];\n path: string;\n query?: Record<string, string | string[]>;\n body?: unknown;\n}\n\nexport interface RouteRequestOverrides {\n pathParams?: Record<string, string>;\n query?: Record<string, unknown>;\n body?: Record<string, unknown>;\n /** Route prefix to prepend to the route path (defaults to '/api') */\n prefix?: string;\n}\n\n/**\n * Get route-specific defaults for path fields based on the route.\n * Different routes need different kinds of paths (files vs directories).\n */\nfunction getRouteSpecificPathDefaults(route: ServerRoute): {\n query?: Record<string, unknown>;\n body?: Record<string, unknown>;\n} {\n const routePath = route.path;\n\n // File operations need file paths\n if (\n routePath.includes('/fs/read') ||\n routePath.includes('/fs/write') ||\n routePath.includes('/fs/delete') ||\n routePath.includes('/fs/stat')\n ) {\n return { query: { path: 'test-file.txt' }, body: { path: 'test-file.txt' } };\n }\n\n // Directory operations need directory paths\n if (routePath.includes('/fs/list')) {\n return { query: { path: '.' } };\n }\n\n // mkdir needs a new path to create\n if (routePath.includes('/fs/mkdir')) {\n return { body: { path: 'new-test-dir' } };\n }\n\n // Index/unindex operations\n if (routePath.includes('/workspace/index') || routePath.includes('/workspace/unindex')) {\n return { query: { path: 'test-file.txt' }, body: { path: 'test-file.txt' } };\n }\n\n // Workflow stream routes reject runIds whose run already finished (409),\n // so each request needs a fresh runId instead of the shared 'test-run'.\n if (routePath === '/workflows/:workflowId/stream' || routePath === '/agent-builder/:actionId/stream') {\n return { query: { runId: `test-run-${randomUUID()}` } };\n }\n\n // MCP tool execution validates `data` against the tool's input schema and\n // answers 400 when it does not match; the default path targets getWeather.\n if (routePath === '/mcp/:serverId/tools/:toolId/execute') {\n return { body: { data: { location: 'test-location' } } };\n }\n\n return {};\n}\n\nexport function buildRouteRequest(route: ServerRoute, overrides: RouteRequestOverrides = {}): RouteRequestPayload {\n const method = route.method;\n const prefix = normalizeRoutePath(overrides.prefix ?? '/api');\n let path = `${prefix}${route.path}`;\n\n if (route.pathParamSchema) {\n const defaults = getDefaultValidPathParams(route);\n const params = { ...defaults, ...(overrides.pathParams ?? {}) };\n for (const [key, value] of Object.entries(params)) {\n path = path.replace(`:${key}`, encodeURIComponent(String(value)));\n }\n }\n\n const pathDefaults = getRouteSpecificPathDefaults(route);\n const schemaDefaults = getRouteSpecificSchemaDefaults(route);\n\n let query: Record<string, string | string[]> | undefined;\n if (route.queryParamSchema) {\n const generated = generateValidDataFromSchema(route.queryParamSchema) as Record<string, unknown>;\n query = convertQueryValues({\n ...generated,\n ...(schemaDefaults.query ?? {}),\n ...(pathDefaults.query ?? {}),\n ...(overrides.query ?? {}),\n });\n } else if (overrides.query) {\n query = convertQueryValues(overrides.query);\n }\n\n let body: Record<string, unknown> | undefined;\n if (route.bodySchema) {\n const generated = generateValidDataFromSchema(route.bodySchema) as Record<string, unknown>;\n body = {\n ...generated,\n ...(schemaDefaults.body ?? {}),\n ...(pathDefaults.body ?? {}),\n ...(overrides.body ?? {}),\n };\n } else if (overrides.body) {\n body = { ...overrides.body };\n }\n\n return {\n method,\n path,\n query,\n body,\n };\n}\n\nexport function convertQueryValues(values: Record<string, unknown>): Record<string, string | string[]> {\n const query: Record<string, string | string[]> = {};\n const appendValue = (prefix: string, value: unknown) => {\n if (value === undefined || value === null) return;\n if (Array.isArray(value)) {\n // JSON-encode arrays for complex query params (e.g., tags=[\"tag1\",\"tag2\"])\n // Server uses wrapSchemaForQueryParams which expects JSON strings for complex types\n query[prefix] = JSON.stringify(value);\n return;\n }\n if (value instanceof Date) {\n query[prefix] = value.toISOString();\n return;\n }\n if (typeof value === 'object') {\n // JSON-encode objects for complex query params (e.g., dateRange={\"gte\":\"2024-01-01\"})\n // Server uses wrapSchemaForQueryParams which expects JSON strings for complex types\n query[prefix] = JSON.stringify(value);\n return;\n }\n query[prefix] = convertQueryValue(value);\n };\n\n for (const [key, value] of Object.entries(values)) {\n appendValue(key, value);\n }\n return query;\n}\n\nfunction convertQueryValue(value: unknown): string {\n return String(value);\n}\n\n/**\n * Creates a ReadableStream that emits chunks with sensitive data.\n * This simulates what an agent.stream() call would return with request metadata.\n *\n * @param format - The stream format version ('v1' for legacy, 'v2' for current)\n * @returns A ReadableStream with chunks containing sensitive request data\n */\nexport function createStreamWithSensitiveData(format: 'v1' | 'v2' = 'v2'): ReadableStream {\n const sensitiveRequest = {\n body: JSON.stringify({\n model: 'gpt-4',\n messages: [{ role: 'system', content: 'SECRET_SYSTEM_PROMPT' }],\n tools: [{ name: 'secret_tool', description: 'Internal tool' }],\n }),\n };\n\n const chunks =\n format === 'v2'\n ? [\n {\n type: 'step-start',\n runId: 'run-123',\n from: 'AGENT',\n payload: {\n messageId: 'msg-123',\n request: sensitiveRequest,\n warnings: [],\n },\n },\n { type: 'text-delta', textDelta: 'Hello' },\n {\n type: 'step-finish',\n runId: 'run-123',\n from: 'AGENT',\n payload: {\n messageId: 'msg-123',\n metadata: { request: sensitiveRequest },\n output: {\n text: 'Hello',\n steps: [{ request: sensitiveRequest, response: { id: 'resp-1' } }],\n },\n },\n },\n {\n type: 'finish',\n runId: 'run-123',\n from: 'AGENT',\n payload: {\n messageId: 'msg-123',\n metadata: { request: sensitiveRequest },\n output: {\n text: 'Hello',\n steps: [{ request: sensitiveRequest }],\n },\n },\n },\n ]\n : [\n {\n type: 'step-start',\n messageId: 'msg-123',\n request: sensitiveRequest,\n warnings: [],\n },\n { type: 'text-delta', textDelta: 'Hello' },\n {\n type: 'step-finish',\n finishReason: 'stop',\n request: sensitiveRequest,\n },\n {\n type: 'finish',\n finishReason: 'stop',\n request: sensitiveRequest,\n },\n ];\n\n return new ReadableStream({\n start(controller) {\n for (const chunk of chunks) {\n controller.enqueue(chunk);\n }\n controller.close();\n },\n });\n}\n\n/**\n * Creates a ReadableStream for testing per-chunk serialization error handling\n * (https://github.com/mastra-ai/mastra/issues/17821).\n *\n * Emits three chunks:\n * 1. a chunk whose payload contains a BigInt (not JSON-serializable natively — must be coerced to a string)\n * 2. a chunk that cannot be serialized at all (throwing toJSON — must be skipped without killing the stream)\n * 3. a final chunk that must still be delivered after the unserializable one\n *\n * Use {@link expectSerializedStreamChunks} to assert on the consumed result.\n */\nexport function createStreamWithUnserializableChunk(): ReadableStream {\n return new ReadableStream({\n start(controller) {\n controller.enqueue({ type: 'workflow-step-result', payload: { output: { count: 42n } } });\n controller.enqueue({\n type: 'poison',\n toJSON() {\n throw new Error('cannot serialize');\n },\n });\n controller.enqueue({ type: 'workflow-finish', payload: { workflowStatus: 'success' } });\n controller.close();\n },\n });\n}\n\n/**\n * Asserts the chunks consumed from {@link createStreamWithUnserializableChunk}:\n * BigInt coerced to a string, the poison chunk skipped, and the final chunk delivered.\n */\nexport function expectSerializedStreamChunks(chunks: any[]): void {\n const stepResult = chunks.find(c => c.type === 'workflow-step-result');\n expect(stepResult).toBeDefined();\n expect(stepResult.payload.output).toEqual({ count: '42' });\n\n expect(chunks.find(c => c.type === 'poison')).toBeUndefined();\n\n const finish = chunks.find(c => c.type === 'workflow-finish');\n expect(finish, 'chunks after an unserializable chunk must still be delivered').toBeDefined();\n expect(finish.payload.workflowStatus).toBe('success');\n}\n\n/**\n * Helper to consume a stream and parse SSE chunks.\n * Reads all chunks from a stream and parses them from SSE format.\n *\n * @param stream - The ReadableStream to consume (typically response.body)\n * @returns Array of parsed JSON objects from the SSE data lines\n */\nexport async function consumeSSEStream(stream: ReadableStream<Uint8Array> | null): Promise<any[]> {\n if (!stream) return [];\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n const chunks: any[] = [];\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const text = decoder.decode(value);\n // Parse SSE format: \"data: {...}\\n\\n\"\n const lines = text.split('\\n');\n for (const line of lines) {\n if (line.startsWith('data: ') && line !== 'data: [DONE]') {\n try {\n chunks.push(JSON.parse(line.slice(6)));\n } catch {\n // Skip non-JSON lines\n }\n }\n }\n }\n\n return chunks;\n}\n","import { createRoute, HTTPException, SERVER_ROUTES } from '@mastra/server/server-adapter';\nimport type { ServerRoute } from '@mastra/server/server-adapter';\nimport { describe, it, expect, beforeEach } from 'vitest';\nimport { z } from 'zod';\nimport { z as z3 } from 'zod/v3';\n\nimport { createRouteTestSuite } from './route-test-suite';\nimport { expectValidSchema } from './route-test-utils';\nimport { buildRouteRequest, createDefaultTestContext, parseDatesInResponse } from './test-helpers';\nimport type { AdapterTestContext, AdapterTestSuiteConfig, HttpRequest } from './test-helpers';\n\n/**\n * Creates a standardized integration test suite for server adapters (Express/Hono)\n *\n * Tests the complete HTTP request/response cycle:\n * - Parameter extraction from URL/query/body\n * - Schema validation\n * - Handler execution\n * - Response formatting\n *\n * Uses auto-generated test data from route schemas.\n * For specific test scenarios, write additional tests outside the factory.\n */\nexport function createRouteAdapterTestSuite(config: AdapterTestSuiteConfig) {\n const { suiteName = 'Route Adapter Integration', setupAdapter, executeHttpRequest, createTestContext } = config;\n\n describe('Route Validation', () => {\n createRouteTestSuite({\n routes: SERVER_ROUTES,\n });\n });\n\n describe(suiteName, () => {\n let context: AdapterTestContext;\n let app: any;\n let setup: Awaited<ReturnType<typeof setupAdapter>>;\n\n beforeEach(async () => {\n // Create test context - use provided or default\n if (createTestContext) {\n const result = createTestContext();\n context = result instanceof Promise ? await result : result;\n } else {\n context = await createDefaultTestContext();\n }\n\n // Setup adapter and app\n setup = await setupAdapter(context);\n app = setup.app;\n });\n\n if (config.supportsPostQueryRequestContext) {\n it('merges query requestContext into POST route handlers', async () => {\n await setup.adapter.registerRoute(app, {\n method: 'POST',\n path: '/test/query-request-context',\n responseType: 'json',\n bodySchema: z.object({ data: z.string() }),\n handler: async ({ requestContext }: { requestContext?: { get: (key: string) => unknown } }) => ({\n userId: requestContext?.get('userId'),\n }),\n });\n\n const response = await executeHttpRequest(app, {\n method: 'POST',\n path: '/api/test/query-request-context',\n query: { requestContext: JSON.stringify({ userId: 'query-user-123' }) },\n body: { data: 'test' },\n });\n\n expect(response.status).toBe(200);\n expect(response.data).toEqual({ userId: 'query-user-123' });\n });\n }\n\n it('ignores special object keys in query params while preserving legitimate params', async () => {\n await setup.adapter.registerRoute(app, {\n method: 'GET',\n path: '/test/query-special-keys',\n responseType: 'json',\n handler: async (params: any) => ({\n filter: typeof params.filter === 'string' ? JSON.parse(params.filter) : null,\n tag: params.tag ?? null,\n keys: Object.keys(params).filter(\n k =>\n ![\n 'mastra',\n 'requestContext',\n 'tools',\n 'taskStore',\n 'abortSignal',\n 'registeredTools',\n 'routePrefix',\n 'request',\n ].includes(k),\n ),\n }),\n });\n\n const response = await executeHttpRequest(app, {\n method: 'GET',\n path: '/api/test/query-special-keys',\n query: Object.fromEntries([\n // Keys that must never be written onto parsed objects\n ['__proto__[polluted]', 'yes'],\n ['constructor[prototype]', 'yes'],\n ['prototype[x]', 'yes'],\n ['filter[__proto__]', 'yes'],\n // Legitimate params alongside them\n ['filter[status]', 'active'],\n ['tag', ['a', 'b']],\n ['page', '2'],\n ]),\n });\n\n expect(response.status).toBe(200);\n const data = response.data as any;\n // Bracket-notation groups still reconstruct as before\n expect(data.filter).toEqual({ status: 'active' });\n // Repeated keys still arrive (as an array where the framework preserves\n // them; some frameworks collapse them to the last value — both are the\n // pre-existing behavior and must not change)\n const tags = Array.isArray(data.tag) ? data.tag : [data.tag];\n expect(tags).toContain('b');\n // Special keys are dropped, not parsed\n expect(data.keys).not.toContain('__proto__');\n expect(data.keys).not.toContain('constructor');\n expect(data.keys).not.toContain('prototype');\n // The process-wide Object.prototype must be untouched\n expect(({} as any).polluted).toBeUndefined();\n });\n\n describe.each([\n {\n version: 'v3',\n recordSchema: z3.record(z3.string(), z3.string()),\n objectSchema: z3.object({ limit: z3.number().default(10) }),\n },\n {\n version: 'v4',\n recordSchema: z.record(z.string(), z.string()),\n objectSchema: z.object({ limit: z.number().default(10) }),\n },\n ])('Zod $version record body validation', ({ recordSchema, objectSchema }) => {\n beforeEach(async () => {\n await setup.adapter.registerRoute(app, {\n method: 'DELETE',\n path: '/test/record-body',\n responseType: 'json',\n bodySchema: recordSchema,\n handler: async () => ({ success: true }),\n });\n await setup.adapter.registerRoute(app, {\n method: 'DELETE',\n path: '/test/object-body',\n responseType: 'json',\n bodySchema: objectSchema,\n handler: async ({ limit }: { limit: number }) => ({ limit }),\n });\n });\n\n it('does not convert missing record bodies to empty objects', async () => {\n const response = await executeHttpRequest(app, { method: 'DELETE', path: '/api/test/record-body' });\n // Some framework parsers already supply {} before adapter validation runs.\n const alreadyNormalized = config.emptyBodyNormalization?.withoutContentType === 'empty-object';\n expect(response.status).toBe(alreadyNormalized ? 200 : 400);\n if (!alreadyNormalized) {\n expect(response.data).toMatchObject({ error: 'Invalid request body', issues: [{ field: 'root' }] });\n }\n });\n\n it('accepts explicitly empty record bodies', async () => {\n const response = await executeHttpRequest(app, { method: 'DELETE', path: '/api/test/record-body', body: {} });\n expect(response.status).toBe(200);\n expect(response.data).toEqual({ success: true });\n });\n\n it('keeps bodyless object field defaults', async () => {\n const response = await executeHttpRequest(app, { method: 'DELETE', path: '/api/test/object-body' });\n expect(response.status).toBe(200);\n expect(response.data).toEqual({ limit: 10 });\n });\n });\n\n describe('Whole-body defaults over HTTP', () => {\n const normalization = config.emptyBodyNormalization ?? {\n withoutContentType: 'undefined',\n withJsonContentType: 'undefined',\n };\n\n beforeEach(async () => {\n await setup.adapter.registerRoute(\n app,\n createRoute({\n method: 'POST',\n path: '/test/root-default',\n responseType: 'json',\n bodySchema: z.object({ marker: z.string().optional() }).default({ marker: 'root-default' }),\n handler: async ({ marker }) => ({ marker }),\n }),\n );\n });\n\n it.each([\n {\n label: 'omitted body without Content-Type',\n body: undefined,\n headers: undefined,\n normalized: normalization.withoutContentType,\n },\n {\n label: 'zero-byte JSON body',\n body: undefined,\n headers: { 'Content-Type': 'application/json' },\n normalized: normalization.withJsonContentType,\n },\n {\n label: 'explicit empty JSON object',\n body: {},\n headers: { 'Content-Type': 'application/json' },\n normalized: 'empty-object',\n },\n ])('$label respects framework normalization', async ({ body, headers, normalized }) => {\n const response = await executeHttpRequest(app, {\n method: 'POST',\n path: '/api/test/root-default',\n body,\n headers,\n });\n if (normalized === 'empty-string') {\n expect(response.status).toBe(400);\n expect(response.data).toEqual({\n error: 'Invalid request body',\n issues: [{ field: 'root', message: expect.stringContaining('string') }],\n });\n } else {\n expect(response.status).toBe(200);\n expect(response.data).toEqual(normalized === 'undefined' ? { marker: 'root-default' } : {});\n }\n });\n });\n\n describe('Scalar JSON body validation', () => {\n beforeEach(async () => {\n const route = createRoute({\n method: 'DELETE',\n path: '/test/scalar-body',\n responseType: 'json',\n bodySchema: z\n .union([z.null(), z.literal(false), z.literal(0), z.literal('')])\n .transform(value => ({ value })),\n handler: async ({ value }) => ({ value }),\n onValidationError: () => ({ status: 400, body: { error: 'Scalar schema rejected body' } }),\n });\n await setup.adapter.registerRoute(app, route);\n });\n it.each([null, false, 0, ''])('validates scalar JSON through the route schema: %j', async body => {\n const accepted = await executeHttpRequest(app, {\n method: 'DELETE',\n path: '/api/test/scalar-body',\n body,\n });\n expect(accepted.status).toBe(200);\n expect(accepted.data).toEqual({ value: body });\n });\n it('returns the route validation response for an invalid scalar', async () => {\n const rejected = await executeHttpRequest(app, {\n method: 'DELETE',\n path: '/api/test/scalar-body',\n body: true,\n });\n expect(rejected.status).toBe(400);\n expect(rejected.data).toEqual({ error: 'Scalar schema rejected body' });\n });\n });\n\n describe.each(['POST', 'PUT', 'PATCH', 'DELETE'] as const)('%s required body validation', method => {\n beforeEach(async () => {\n await setup.adapter.registerRoute(\n app,\n createRoute({\n method,\n path: '/test/required-body',\n responseType: 'json',\n bodySchema: z.object({ itemIds: z.array(z.string().min(1)).min(1) }),\n handler: async ({ itemIds }) => ({ itemIds }),\n onValidationError: () => ({ status: 400, body: { error: 'Required schema rejected body' } }),\n }),\n );\n await setup.adapter.registerRoute(\n app,\n createRoute({\n method,\n path: '/test/optional-body',\n responseType: 'json',\n bodySchema: z.object({ name: z.string().optional(), limit: z.number().default(10) }),\n handler: async ({ limit }) => ({ limit }),\n }),\n );\n });\n\n it.each([undefined, null, false, 0, '', {}, { itemIds: [] }, { itemIds: [''] }])(\n 'rejects missing or invalid required input %#',\n async body => {\n const response = await executeHttpRequest(app, {\n method,\n path: '/api/test/required-body',\n body,\n });\n expect(response.status).toBe(400);\n expect(response.data).toEqual({ error: 'Required schema rejected body' });\n },\n );\n\n it('passes valid required input to the handler', async () => {\n const body = { itemIds: ['item-1'] };\n const response = await executeHttpRequest(app, {\n method,\n path: '/api/test/required-body',\n body,\n });\n expect(response.status).toBe(200);\n expect(response.data).toEqual(body);\n });\n\n it('applies field defaults when the body is omitted', async () => {\n const response = await executeHttpRequest(app, {\n method,\n path: '/api/test/optional-body',\n });\n expect(response.status).toBe(200);\n expect(response.data).toEqual({ limit: 10 });\n });\n });\n\n it.each([\n { body: {}, field: 'itemIds' },\n { body: { itemIds: [''] }, field: 'itemIds.0' },\n ])('returns standard validation issues for $field', async ({ body, field }) => {\n await setup.adapter.registerRoute(\n app,\n createRoute({\n method: 'DELETE',\n path: '/test/default-validation-error',\n responseType: 'json',\n bodySchema: z.object({ itemIds: z.array(z.string().min(1)).min(1) }),\n handler: async ({ itemIds }) => ({ itemIds }),\n }),\n );\n const response = await executeHttpRequest(app, {\n method: 'DELETE',\n path: '/api/test/default-validation-error',\n body,\n });\n expect(response.status).toBe(400);\n expect(response.data).toEqual({\n error: 'Invalid request body',\n issues: [{ field, message: expect.any(String) }],\n });\n });\n\n it('preserves bodyless create-run requests with optional fields', async () => {\n const response = await executeHttpRequest(app, {\n method: 'POST',\n path: '/api/workflows/test-workflow/create-run',\n });\n expect(response.status).toBe(200);\n expect(response.data).toMatchObject({ runId: expect.any(String) });\n });\n\n // Test deprecated routes separately - just verify they're marked correctly\n const deprecatedRoutes = SERVER_ROUTES.filter(r => r.deprecated);\n\n // Group deprecated routes by first path segment\n const deprecatedByCategory = deprecatedRoutes.reduce(\n (acc, route) => {\n const category = route.path.split('/')[1] || 'root';\n if (!acc[category]) acc[category] = [];\n acc[category].push(route);\n return acc;\n },\n {} as Record<string, typeof deprecatedRoutes>,\n );\n\n Object.entries(deprecatedByCategory).forEach(([category, routes]) => {\n describe(category, () => {\n routes.forEach(route => {\n const testName = `${route.method} ${route.path}`;\n describe(testName, () => {\n it('should be marked as deprecated', () => {\n expect(route.deprecated).toBe(true);\n expect(route.openapi?.deprecated).toBe(true);\n });\n });\n });\n });\n });\n\n // Test non-deprecated routes with full test suite\n // Skip MCP transport routes (mcp-http, mcp-sse) - they require MCP protocol handling\n // and are tested separately via mcp-transport-test-suite\n // Skip auth routes that require specific providers (SSO, credentials) - they return 404\n // when providers aren't configured, which is expected behavior\n // Note: Route paths in SERVER_ROUTES don't include /api prefix\n const authRoutesRequiringProviders = [\n '/auth/sso/login',\n '/auth/sso/callback',\n '/auth/credentials/sign-in',\n '/auth/credentials/sign-up',\n '/auth/refresh',\n // Requires a provider that can actually end a session (destroySession,\n // getClearSessionHeaders, or getLogoutUrl). Without one there is nothing to log out\n // of, so it 404s like /auth/refresh. Per-status behavior is covered in\n // packages/server/src/server/handlers/auth.test.ts.\n '/auth/logout',\n // Requires an authenticated admin caller (MASTRA_USER_PERMISSIONS_KEY is a reserved\n // request-context key set only by the auth middleware) and an RBAC provider with\n // getPermissionsForRole. Per-status behavior is covered in\n // packages/server/src/server/handlers/auth.test.ts.\n '/auth/roles/:roleId/permissions',\n ];\n // Skip routes that require external dependencies (APIs)\n const routesRequiringExternalDeps = [\n // skills-sh routes that require external API calls (GitHub, skills.sh)\n '/workspaces/:workspaceId/skills-sh/search',\n '/workspaces/:workspaceId/skills-sh/popular',\n '/workspaces/:workspaceId/skills-sh/preview',\n '/workspaces/:workspaceId/skills-sh/install',\n '/workspaces/:workspaceId/skills-sh/remove',\n '/workspaces/:workspaceId/skills-sh/update',\n // observational memory routes require OM-enabled agent configuration\n '/memory/observational-memory',\n '/memory/observational-memory/buffer-status',\n // skill publish requires blob storage not available in InMemoryStore\n '/stored/skills/:storedSkillId/publish',\n // POST /stored/agents requires a builder-resolved model policy and a\n // model-allowlist-compatible payload; the generic test suite produces a\n // payload that fails allowlist enforcement. Behavior is covered by\n // packages/server/src/server/handlers/stored-agents.test.ts.\n '/stored/agents',\n // Favorites toggles require an existing stored entity AND an\n // authenticated caller (callerId is read from the auth-middleware\n // request context). Behavior is covered by stored-{agent,skill}-favorites\n // unit tests; the generic test suite can't satisfy both prereqs.\n '/stored/agents/:storedAgentId/favorite',\n '/stored/skills/:storedSkillId/favorite',\n // Change request creation requires a source-control provider that can open\n // PRs; the generic test sutie has no provider. Covered by stored-agents tests.\n '/stored/agents/:storedAgentId/change-request',\n // Builder registry routes that require external API calls + builder config\n '/editor/builder/registries',\n '/editor/builder/registries/:registryId/search',\n '/editor/builder/registries/:registryId/popular',\n '/editor/builder/registries/:registryId/preview',\n '/editor/builder/registries/:registryId/install',\n // Long-lived SSE streams: stay open until the client disconnects, so the\n // test test suite's real-HTTP-server cleanup (server.close awaiting drain)\n // hangs. These routes' behavior is exercised in unit tests.\n '/background-tasks/stream',\n '/agents/:agentId/observe',\n // Recover requires both a durable agent and a persisted workflow run.\n // Its stateful behavior is covered by packages/server/src/server/handlers/agents.test.ts.\n '/agents/:agentId/recover',\n // Reading a submitted plan requires an agent exposing the core submit_plan tool\n // and a workspace filesystem containing the plan. The generic agent has neither;\n // capability, path, and filesystem behavior are covered by plans.test.ts.\n '/agents/:agentId/plans/file',\n // Tool-provider connection routes that require a persisted connection\n // row matching the supplied connectionId. The test suite uses a generic\n // 'test-connection-id' that isn't seeded, so the fail-closed ownership\n // guard returns 403. Behavior is covered by\n // packages/server/src/server/handlers/tool-providers.test.ts.\n '/tool-providers/:providerId/connections/:connectionId',\n '/tool-providers/:providerId/connections/:connectionId/usage',\n // Tool-provider authorize + connection-status routes require a real\n // OAuth provider config; the generic test suite produces a payload the\n // mock provider can't authorize. Covered by tool-providers.test.ts.\n '/tool-providers/:providerId/authorize',\n '/tool-providers/:providerId/connection-status',\n // Tool-provider auth-status requires a live provider auth lookup that\n // the mock provider doesn't implement. Covered by tool-providers.test.ts.\n '/tool-providers/:providerId/auth-status/:authId',\n // Tool-provider connections list relies on storage rows being seeded\n // for the test author. Covered by tool-providers.test.ts.\n '/tool-providers/:providerId/connections',\n // Experiment deletion requires a persisted experiment matching the generated\n // experimentId. The generic test context does not seed dataset storage;\n // deletion behavior is covered by datasets.test.ts.\n '/experiments/:experimentId',\n ];\n // Routes under these prefixes are excluded (e.g. /datasets needs a datasets storage domain)\n const excludedPrefixes = [\n '/datasets',\n // Agent-controller routes resolve a registered AgentController via\n // mastra.getAgentController(id) and operate on a live session keyed by\n // resourceId. The generic test context registers no controller, so every\n // route fails closed with 404. Behavior is covered by\n // packages/server/src/server/handlers/agent-controller.test.ts.\n '/agent-controller',\n ];\n const isExcluded = (r: ServerRoute) =>\n r.deprecated ||\n r.responseType === 'mcp-http' ||\n r.responseType === 'mcp-sse' ||\n authRoutesRequiringProviders.includes(r.path) ||\n routesRequiringExternalDeps.includes(r.path) ||\n excludedPrefixes.some(prefix => r.path.startsWith(prefix));\n const activeRoutes = SERVER_ROUTES.filter(r => !isExcluded(r));\n\n // Group routes by first path segment (e.g., /agents/:id/tools -> 'agents')\n const routesByCategory = activeRoutes.reduce(\n (acc, route) => {\n const category = route.path.split('/')[1] || 'root';\n if (!acc[category]) acc[category] = [];\n acc[category].push(route);\n return acc;\n },\n {} as Record<string, typeof activeRoutes>,\n );\n\n Object.entries(routesByCategory).forEach(([category, routes]) => {\n describe(category, () => {\n routes.forEach(route => {\n const testName = `${route.method} ${route.path}`;\n describe(testName, () => {\n it('should execute with valid request', async () => {\n // Build HTTP request with auto-generated test data\n const request = buildRouteRequest(route);\n\n // Convert to HttpRequest format\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: request.body,\n };\n\n // Execute through adapter\n const response = await executeHttpRequest(app, httpRequest);\n\n // Validate response\n expect(response.status).toBeLessThan(400);\n\n if (route.responseType === 'json') {\n expect(response.type).toBe('json');\n expect(response.data).toBeDefined();\n\n // Validate response schema (if defined)\n if (route.responseSchema) {\n const parsedData = parseDatesInResponse(response.data, route.responseSchema);\n expectValidSchema(route.responseSchema, parsedData);\n }\n\n // Verify JSON is serializable (no circular refs, functions, etc)\n expect(() => JSON.stringify(response.data)).not.toThrow();\n } else if (route.responseType === 'stream') {\n expect(response.type).toBe('stream');\n expect(response.stream).toBeDefined();\n\n // Verify stream is consumable (has getReader or is async iterable)\n const hasReader = response.stream && typeof (response.stream as any).getReader === 'function';\n const isAsyncIterable =\n response.stream &&\n typeof (response.stream as AsyncIterable<unknown>)[Symbol.asyncIterator] === 'function';\n expect(hasReader || isAsyncIterable).toBe(true);\n }\n });\n\n // Error handling tests for routes with entity IDs\n if (route.path.includes(':agentId')) {\n it('should return 404 when agent not found', async () => {\n // Build request with non-existent agent\n const request = buildRouteRequest(route, {\n pathParams: { agentId: 'non-existent-agent' },\n });\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: request.body,\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n // Expect 404 status\n expect(response.status).toBe(404);\n });\n }\n\n if (route.path.includes(':workflowId')) {\n it('should return 404 when workflow not found', async () => {\n const request = buildRouteRequest(route, {\n pathParams: { workflowId: 'non-existent-workflow' },\n });\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: request.body,\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n expect(response.status).toBe(404);\n });\n }\n\n if (route.path.includes(':backgroundTaskId')) {\n it('should return 404 when background task not found', async () => {\n const request = buildRouteRequest(route, {\n pathParams: { backgroundTaskId: 'non-existent-background-task' },\n });\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: request.body,\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n expect(response.status).toBe(404);\n });\n }\n\n // MCP server 404 tests\n if (route.path.includes(':serverId')) {\n it('should return 404 when MCP server not found (via :serverId)', async () => {\n const request = buildRouteRequest(route, {\n pathParams: { serverId: 'non-existent-server' },\n });\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: request.body,\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n expect(response.status).toBe(404);\n });\n }\n\n // MCP v0 server detail 404 test (uses :id instead of :serverId)\n if (route.path.includes('/mcp/v0/servers/:id')) {\n it('should return 404 when MCP server not found (via :id)', async () => {\n const request = buildRouteRequest(route, {\n pathParams: { id: 'non-existent-server' },\n });\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: request.body,\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n expect(response.status).toBe(404);\n });\n }\n\n // Processor 404 tests\n if (route.path.includes(':processorId')) {\n it('should return 404 when processor not found', async () => {\n const request = buildRouteRequest(route, {\n pathParams: { processorId: 'non-existent-processor' },\n });\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: request.body,\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n expect(response.status).toBe(404);\n });\n }\n\n // Stream consumption test\n if (route.responseType === 'stream') {\n it('should be consumable via stream reader', async () => {\n const request = buildRouteRequest(route);\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: request.body,\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n expect(response.status).toBeLessThan(400);\n expect(response.stream).toBeDefined();\n\n // Try to consume the stream\n if (typeof (response.stream as any).getReader === 'function') {\n // Web Streams API\n const reader = (response.stream as ReadableStream).getReader();\n const firstChunk = await reader.read();\n expect(firstChunk).toBeDefined();\n // Don't validate chunk structure - that's handler's job\n reader.releaseLock();\n } else if (typeof (response.stream as AsyncIterable<unknown>)[Symbol.asyncIterator] === 'function') {\n // Async iterable\n const iterator = (response.stream as AsyncIterable<unknown>)[Symbol.asyncIterator]();\n const firstChunk = await iterator.next();\n expect(firstChunk).toBeDefined();\n }\n });\n }\n\n // Schema validation tests - only for routes with query or body schemas\n if (route.queryParamSchema || route.bodySchema) {\n it('should return 400 when schema validation fails', async () => {\n const request = buildRouteRequest(route);\n\n let httpRequest: HttpRequest;\n\n if (route.queryParamSchema) {\n // Add invalid query param (add an object where string/number expected)\n httpRequest = {\n method: request.method,\n path: request.path,\n query: {\n ...(request.query || {}),\n invalidQueryParam: { nested: 'object' } as any,\n },\n body: request.body,\n };\n } else if (route.bodySchema) {\n // Keep valid request but add an invalid field with wrong type\n httpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: {\n ...(typeof request.body === 'object' && request.body !== null ? request.body : {}),\n invalidBodyField: { deeply: { nested: 'object' } },\n },\n };\n } else {\n // Shouldn't happen, but fallback\n httpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: request.body,\n };\n }\n\n const response = await executeHttpRequest(app, httpRequest);\n\n // Routes may use the shared 400 response or a route-specific 422 response.\n // Lenient schemas may still succeed if they ignore unknown fields.\n expect([200, 201, 400, 422]).toContain(response.status);\n\n if (response.status === 400 || response.status === 422) {\n expect(response.type).toBe('json');\n\n // Verify error response has helpful structure\n const errorData = response.data as any;\n expect(errorData).toBeDefined();\n expect(errorData.error || errorData.message || errorData.details).toBeDefined();\n }\n });\n }\n\n // RequestContext tests - test for POST/PUT routes that accept body\n if (['POST', 'PUT'].includes(route.method) && route.bodySchema) {\n it('should accept requestContext in body', async () => {\n const request = buildRouteRequest(route);\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: {\n ...(typeof request.body === 'object' && request.body !== null ? request.body : {}),\n requestContext: { userId: 'test-user-123', sessionId: 'session-456' },\n },\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n // Should succeed - requestContext is optional and should not cause errors\n expect(response.status).toBeLessThan(500);\n });\n }\n\n // Body field spreading test - for POST/PUT routes with body\n const bodySchema = route.bodySchema;\n if (['POST', 'PUT'].includes(route.method) && bodySchema) {\n it('should spread body fields to handler params', async () => {\n const request = buildRouteRequest(route);\n\n // Add a unique field to the body\n const testField = 'testBodyField';\n const testValue = 'testValue123';\n\n const body = {\n ...(typeof request.body === 'object' && request.body !== null ? request.body : {}),\n [testField]: testValue,\n };\n const strictBody = !bodySchema.safeParse(body).success;\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body,\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n if (strictBody) {\n // Strict schemas must surface either the shared or route-specific validation rejection.\n expect([400, 422]).toContain(response.status);\n } else {\n // lenient schema: unknown field must be ignored, request must succeed\n expect(response.status).toBeLessThan(400);\n }\n });\n }\n });\n });\n });\n });\n\n // Additional cross-route tests\n describe('Cross-Route Tests', () => {\n // Test array query parameters for ALL GET routes\n const getRoutes = SERVER_ROUTES.filter(r => r.method === 'GET' && !isExcluded(r));\n getRoutes.forEach(route => {\n it(`should handle array query parameters for ${route.method} ${route.path}`, async () => {\n const request = buildRouteRequest(route);\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: {\n ...(request.query || {}),\n tags: ['tag1', 'tag2', 'tag3'],\n },\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n // Should handle array params without error\n if (response.status >= 500) {\n console.error(`[FAIL] ${route.method} ${route.path} returned ${response.status}`, response.data);\n }\n expect(response.status).toBeLessThan(500);\n });\n });\n\n // Test error response structure for ALL routes with agentId\n const agentRoutes = SERVER_ROUTES.filter(r => r.path.includes(':agentId') && !r.deprecated);\n agentRoutes.forEach(route => {\n it(`should return valid error response structure for ${route.method} ${route.path}`, async () => {\n const request = buildRouteRequest(route, {\n pathParams: { agentId: 'non-existent-agent-error-test' },\n });\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: request.body,\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n expect(response.status).toBe(404);\n expect(response.type).toBe('json');\n\n // Verify error has a structured format\n const errorData = response.data as any;\n expect(errorData).toBeDefined();\n\n // Should have at least one of these error fields\n const hasErrorField =\n errorData.error !== undefined ||\n errorData.message !== undefined ||\n errorData.details !== undefined ||\n errorData.statusCode !== undefined;\n\n expect(hasErrorField).toBe(true);\n });\n });\n\n // Test empty body for ALL POST routes with body schema\n const postRoutesWithBody = SERVER_ROUTES.filter(r => r.method === 'POST' && r.bodySchema && !isExcluded(r));\n postRoutesWithBody.forEach(route => {\n it(`should handle empty body for ${route.method} ${route.path}`, async () => {\n const request = buildRouteRequest(route);\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: {}, // Empty body - missing required fields\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n // Should return the shared or route-specific validation response for missing fields\n // (or 200/201 if all fields are optional).\n expect([200, 201, 400, 422]).toContain(response.status);\n\n if (response.status === 400 || response.status === 422) {\n expect(response.type).toBe('json');\n const errorData = response.data as any;\n expect(errorData).toBeDefined();\n // Verify error response has helpful structure when validation is explicit\n if (!(errorData.error || errorData.message || errorData.details)) {\n console.warn(`[WARN] ${route.method} ${route.path} 400 response missing error fields`, errorData);\n }\n }\n });\n });\n });\n\n describe('Custom HTTPException responses', () => {\n async function setupCustomErrorRoutes() {\n let handlerCalls = 0;\n const routes: ServerRoute<any, any, any>[] = [\n {\n method: 'GET',\n path: '/custom/http-error-json',\n responseType: 'json',\n handler: async () => {\n handlerCalls++;\n throw new HTTPException(409, {\n res: Response.json(\n { code: 'TRACE_QUERY_CURSOR_CONFLICT', message: 'The cursor does not match the query' },\n { headers: { 'X-Trace-Error': 'cursor' } },\n ),\n });\n },\n },\n {\n method: 'GET',\n path: '/custom/http-error-text',\n responseType: 'json',\n handler: async () => {\n handlerCalls++;\n throw new HTTPException(418, {\n res: new Response('custom text', {\n headers: { 'Content-Type': 'text/custom', 'X-Custom-Error': 'true' },\n }),\n });\n },\n },\n {\n method: 'GET',\n path: '/custom/http-error-fallback',\n responseType: 'json',\n handler: async () => {\n handlerCalls++;\n throw new HTTPException(404, { message: 'Legacy fallback' });\n },\n },\n ];\n const mutableServerRoutes = SERVER_ROUTES as ServerRoute[];\n const originalLength = mutableServerRoutes.length;\n mutableServerRoutes.push(...routes);\n try {\n const setup = await setupAdapter(await createDefaultTestContext());\n return { app: setup.app, getHandlerCalls: () => handlerCalls };\n } finally {\n mutableServerRoutes.splice(originalLength);\n }\n }\n\n it('preserves an attached JSON response and headers', async () => {\n const custom = await setupCustomErrorRoutes();\n\n const response = await executeHttpRequest(custom.app, {\n method: 'GET',\n path: '/api/custom/http-error-json',\n });\n\n expect(response.status).toBe(409);\n expect(response.headers['content-type']).toContain('application/json');\n expect(response.headers['x-trace-error']).toBe('cursor');\n expect(response.data).toEqual({\n code: 'TRACE_QUERY_CURSOR_CONFLICT',\n message: 'The cursor does not match the query',\n });\n expect(custom.getHandlerCalls()).toBe(1);\n });\n\n it('preserves an attached text response without JSON wrapping', async () => {\n const custom = await setupCustomErrorRoutes();\n\n const response = await executeHttpRequest(custom.app, {\n method: 'GET',\n path: '/api/custom/http-error-text',\n });\n\n expect(response.status).toBe(418);\n expect(response.headers['content-type']).toContain('text/custom');\n expect(response.headers['x-custom-error']).toBe('true');\n expect(response.data).toBe('custom text');\n expect(custom.getHandlerCalls()).toBe(1);\n });\n\n it('retains the JSON fallback for message-only HTTP exceptions', async () => {\n const custom = await setupCustomErrorRoutes();\n\n const response = await executeHttpRequest(custom.app, {\n method: 'GET',\n path: '/api/custom/http-error-fallback',\n });\n\n expect(response.status).toBe(404);\n expect(response.data).toEqual({ error: 'Legacy fallback' });\n expect(custom.getHandlerCalls()).toBe(1);\n });\n });\n\n // Route prefix tests\n describe('Route Prefix', () => {\n it('should register routes at prefixed paths without double /api', async () => {\n // Create a new adapter with a custom prefix\n const prefixedSetup = await setupAdapter(context, { prefix: '/v2' });\n const prefixedApp = prefixedSetup.app;\n\n // Request the expected path: /v2/agents (not /v2/api/agents)\n const response = await executeHttpRequest(prefixedApp, {\n method: 'GET',\n path: '/v2/agents',\n });\n\n // Should succeed - routes should be at /v2/agents\n expect(response.status).toBeLessThan(400);\n });\n\n it('should not have routes at double /api path when prefix is set', async () => {\n // Create a new adapter with a custom prefix\n const prefixedSetup = await setupAdapter(context, { prefix: '/v2' });\n const prefixedApp = prefixedSetup.app;\n\n // The buggy path /v2/api/agents should NOT work\n const response = await executeHttpRequest(prefixedApp, {\n method: 'GET',\n path: '/v2/api/agents',\n });\n\n // Should return 404 - this path should not exist\n expect(response.status).toBe(404);\n });\n\n it('should normalize prefix with trailing slash', async () => {\n // Create adapter with trailing slash in prefix\n const prefixedSetup = await setupAdapter(context, { prefix: '/mastra/' });\n const prefixedApp = prefixedSetup.app;\n\n // Request should work at normalized path /mastra/agents (not /mastra//agents)\n const response = await executeHttpRequest(prefixedApp, {\n method: 'GET',\n path: '/mastra/agents',\n });\n\n // Should succeed - trailing slash should be normalized\n expect(response.status).toBeLessThan(400);\n });\n\n it('should normalize prefix without leading slash', async () => {\n // Create adapter without leading slash in prefix\n const prefixedSetup = await setupAdapter(context, { prefix: 'mastra' });\n const prefixedApp = prefixedSetup.app;\n\n // Request should work at normalized path /mastra/agents\n const response = await executeHttpRequest(prefixedApp, {\n method: 'GET',\n path: '/mastra/agents',\n });\n\n // Should succeed - leading slash should be added\n expect(response.status).toBeLessThan(400);\n });\n\n it('should not have routes at double-slash path when prefix has trailing slash', async () => {\n // Create adapter with trailing slash in prefix\n const prefixedSetup = await setupAdapter(context, { prefix: '/mastra/' });\n const prefixedApp = prefixedSetup.app;\n\n // The double-slash path /mastra//agents should NOT work\n const response = await executeHttpRequest(prefixedApp, {\n method: 'GET',\n path: '/mastra//agents',\n });\n\n // Should return 404 - double-slash path should not exist\n expect(response.status).toBe(404);\n });\n });\n });\n}\n","import { Mastra } from '@mastra/core/mastra';\nimport type { MCPServer } from '@mastra/mcp';\nimport { describe, it, expect, beforeEach } from 'vitest';\nimport { createDefaultTestContext } from './test-helpers';\nimport type { AdapterTestContext, AdapterTestSuiteConfig } from './test-helpers';\n\n/**\n * Creates a standardized integration test suite for MCP registry routes\n *\n * Tests the 5 MCP registry routes work correctly with any adapter:\n * - List MCP servers\n * - Get MCP server details\n * - List MCP server tools\n * - Get MCP server tool details\n * - Execute MCP server tool\n *\n * Usage:\n * ```ts\n * describe('Hono MCP Routes', () => {\n * createMCPRouteTestSuite({\n * suiteName: 'Hono Adapter',\n * setupAdapter: async (context) => {\n * const app = new Hono();\n * const adapter = new MastraServer({ app, mastra: context.mastra, ... });\n * await adapter.init(); // Registers context, auth, and all routes\n * return { app, adapter };\n * },\n * executeHttpRequest: async (app, req) => {\n * const res = await app.request(req.path + (req.query ? '?' + new URLSearchParams(req.query).toString() : ''));\n * return { status: res.status, type: 'json', data: await res.json() };\n * }\n * });\n * });\n * ```\n */\nexport function createMCPRouteTestSuite(config: AdapterTestSuiteConfig) {\n const { suiteName = 'MCP Registry Routes Integration', setupAdapter, executeHttpRequest, createTestContext } = config;\n\n describe(suiteName, () => {\n let context: AdapterTestContext;\n let app: any;\n let mcpServer1: MCPServer;\n let mcpServer2: MCPServer;\n\n beforeEach(async () => {\n // Create test context - use provided or default\n if (createTestContext) {\n const result = createTestContext();\n context = result instanceof Promise ? await result : result;\n } else {\n context = await createDefaultTestContext();\n }\n\n const setup = await setupAdapter(context);\n app = setup.app;\n const mastra = setup.adapter.mastra;\n mcpServer1 = mastra.getMCPServerById('test-server-1');\n mcpServer2 = mastra.getMCPServerById('test-server-2');\n }, 30000);\n\n describe('GET /api/mcp/v0/servers', () => {\n it('should list MCP servers', async () => {\n const res = await executeHttpRequest(app, {\n method: 'GET',\n path: '/api/mcp/v0/servers',\n });\n\n expect(res.status).toBe(200);\n expect(res.data).toMatchObject({\n servers: expect.arrayContaining([\n expect.objectContaining({\n name: 'Test Server 1',\n version_detail: expect.objectContaining({\n version: '1.0.0',\n }),\n }),\n expect.objectContaining({\n name: 'Test Server 2',\n version_detail: expect.objectContaining({\n version: '1.1.0',\n }),\n }),\n ]),\n total_count: 2,\n });\n });\n\n it('should handle pagination with page/perPage', async () => {\n const res = await executeHttpRequest(app, {\n method: 'GET',\n path: '/api/mcp/v0/servers',\n query: { perPage: '1', page: '0' },\n });\n\n expect(res.status).toBe(200);\n expect(res.data).toMatchObject({\n servers: expect.any(Array),\n total_count: 2,\n });\n expect((res.data as any).servers).toHaveLength(1);\n expect((res.data as any).next).toContain('perPage=1');\n expect((res.data as any).next).toContain('page=1');\n // Verify the returned server is one of the expected ones\n expect(['Test Server 1', 'Test Server 2']).toContain((res.data as any).servers[0].name);\n });\n\n it('should handle pagination with legacy limit/offset', async () => {\n const res = await executeHttpRequest(app, {\n method: 'GET',\n path: '/api/mcp/v0/servers',\n query: { limit: '1', offset: '0' },\n });\n\n expect(res.status).toBe(200);\n expect(res.data).toMatchObject({\n servers: expect.any(Array),\n total_count: 2,\n });\n expect((res.data as any).servers).toHaveLength(1);\n // Response mirrors request format (legacy limit/offset)\n expect((res.data as any).next).toContain('limit=1');\n expect((res.data as any).next).toContain('offset=1');\n // Verify the returned server is one of the expected ones\n expect(['Test Server 1', 'Test Server 2']).toContain((res.data as any).servers[0].name);\n });\n\n it('should return empty list when no MCP servers registered', async () => {\n // Create a minimal Mastra instance with no MCP servers\n const emptyMastra = new Mastra({});\n\n // Setup adapter with empty Mastra\n const emptySetup = await setupAdapter({\n mastra: emptyMastra,\n tools: {},\n });\n\n const res = await executeHttpRequest(emptySetup.app, {\n method: 'GET',\n path: '/api/mcp/v0/servers',\n });\n\n expect(res.status).toBe(200);\n expect(res.data).toMatchObject({\n servers: [],\n total_count: 0,\n next: null,\n });\n });\n });\n\n describe('GET /api/mcp/v0/servers/:id', () => {\n it('should get server details', async () => {\n const res = await executeHttpRequest(app, {\n method: 'GET',\n path: `/api/mcp/v0/servers/${mcpServer1.id}`,\n });\n\n expect(res.status).toBe(200);\n expect(res.data).toMatchObject({\n id: mcpServer1.id,\n name: 'Test Server 1',\n description: 'Test MCP Server 1',\n version_detail: {\n version: '1.0.0',\n is_latest: true,\n },\n });\n });\n\n it('should return 404 for non-existent server', async () => {\n const res = await executeHttpRequest(app, {\n method: 'GET',\n path: '/api/mcp/v0/servers/non-existent',\n });\n\n expect(res.status).toBe(404);\n expect((res.data as any).error).toContain('not found');\n });\n });\n\n describe('GET /api/mcp/:serverId/tools', () => {\n it('should list server tools', async () => {\n const res = await executeHttpRequest(app, {\n method: 'GET',\n path: `/api/mcp/${mcpServer1.id}/tools`,\n });\n\n expect(res.status).toBe(200);\n expect((res.data as any).tools).toHaveLength(2);\n expect((res.data as any).tools).toEqual(\n expect.arrayContaining([\n expect.objectContaining({ name: 'getWeather' }),\n expect.objectContaining({ name: 'calculate' }),\n ]),\n );\n });\n\n it('should return 404 for non-existent server', async () => {\n const res = await executeHttpRequest(app, {\n method: 'GET',\n path: '/api/mcp/non-existent/tools',\n });\n\n expect(res.status).toBe(404);\n });\n });\n\n describe('GET /api/mcp/:serverId/tools/:toolId', () => {\n it('should get tool details', async () => {\n const res = await executeHttpRequest(app, {\n method: 'GET',\n path: `/api/mcp/${mcpServer1.id}/tools/getWeather`,\n });\n\n expect(res.status).toBe(200);\n expect(res.data).toMatchObject({\n name: 'getWeather',\n description: 'Gets the current weather for a location',\n inputSchema: expect.any(Object),\n });\n });\n\n it('should return 404 for non-existent tool', async () => {\n const res = await executeHttpRequest(app, {\n method: 'GET',\n path: `/api/mcp/${mcpServer1.id}/tools/non-existent`,\n });\n\n expect(res.status).toBe(404);\n });\n });\n\n describe('POST /api/mcp/:serverId/tools/:toolId/execute', () => {\n it('should execute tool', async () => {\n const res = await executeHttpRequest(app, {\n method: 'POST',\n path: `/api/mcp/${mcpServer1.id}/tools/calculate/execute`,\n body: { data: { operation: 'add', a: 5, b: 3 } },\n });\n\n expect(res.status).toBe(200);\n expect((res.data as any).result).toEqual({\n result: 8,\n });\n });\n\n it('should execute tool with location data', async () => {\n const res = await executeHttpRequest(app, {\n method: 'POST',\n path: `/api/mcp/${mcpServer1.id}/tools/getWeather/execute`,\n body: { data: { location: 'San Francisco' } },\n });\n\n expect(res.status).toBe(200);\n expect((res.data as any).result).toMatchObject({\n temperature: 72,\n condition: 'Sunny in San Francisco',\n });\n });\n\n it('should return 404 for non-existent server', async () => {\n const res = await executeHttpRequest(app, {\n method: 'POST',\n path: '/api/mcp/non-existent/tools/calculate/execute',\n body: { data: { operation: 'add', a: 1, b: 2 } },\n });\n\n expect(res.status).toBe(404);\n });\n\n it('should return error for non-existent tool', async () => {\n const res = await executeHttpRequest(app, {\n method: 'POST',\n path: `/api/mcp/${mcpServer1.id}/tools/non-existent/execute`,\n body: { data: {} },\n });\n\n // Current behavior returns 500, ideally should be 404\n expect([404, 500]).toContain(res.status);\n });\n\n it('should handle invalid tool input', async () => {\n const res = await executeHttpRequest(app, {\n method: 'POST',\n path: `/api/mcp/${mcpServer1.id}/tools/calculate/execute`,\n body: { data: { operation: 'invalid', a: 'not-a-number', b: 3 } },\n });\n\n // Input validation may return 400 or 200 with error details depending on implementation\n // Current behavior: zod validation fails during execution, but enum check happens first\n expect([200, 400, 500]).toContain(res.status);\n if (res.status === 200) {\n // If 200, expect error in response body\n expect((res.data as any).error || (res.data as any).result).toBeDefined();\n }\n });\n });\n });\n}\n","import type { ToolsInput } from '@mastra/core/agent';\nimport { MCPServerBase } from '@mastra/core/mcp';\nimport type { MCPServerHTTPOptions, MCPToolExecutionResultV2 } from '@mastra/core/mcp';\nimport { RequestContext } from '@mastra/core/request-context';\nimport { standardSchemaToJSONSchema } from '@mastra/core/schema';\nimport { createTool, isValidationError } from '@mastra/core/tools';\nimport type { InternalCoreTool, MCPToolExecutionContext } from '@mastra/core/tools';\nimport { makeCoreTool } from '@mastra/core/utils';\nimport { z } from 'zod/v4';\n\nconst unavailable = (feature: string) => async (): Promise<never> => {\n throw new Error(`${feature} is not available on a 2026-07-28 server`);\n};\n\n/** The `context.mcp` a 2026-07-28 server builds: the 1.x shape, with server-initiated requests throwing. */\nfunction requestContext2026(): MCPToolExecutionContext {\n const signal = new AbortController().signal;\n return {\n protocolVersion: '2026-07-28',\n extra: {\n signal,\n requestId: 'rest',\n sendNotification: unavailable('extra.sendNotification'),\n sendRequest: unavailable('extra.sendRequest'),\n mcpReq: {\n id: 'rest',\n method: 'tools/call',\n requestState: () => undefined,\n signal,\n send: unavailable('mcpReq.send'),\n notify: unavailable('mcpReq.notify'),\n log: unavailable('mcpReq.log'),\n elicitInput: unavailable('mcpReq.elicitInput'),\n requestSampling: unavailable('mcpReq.requestSampling'),\n },\n },\n elicitation: { sendRequest: unavailable('elicitation.sendRequest') },\n log: async () => {},\n progress: async () => {},\n };\n}\n\n/** Exercises adapter dispatch, not MCP wire-protocol conformance. */\nexport class NativeMCPFixture extends MCPServerBase {\n override readonly mcpVersion = 2 as const;\n constructor() {\n super({\n id: 'native-fixture',\n name: 'Native fixture',\n version: '2.0.0',\n tools: {\n ordinary: createTool({\n id: 'native-fixture-ordinary',\n description: 'Ordinary execution',\n execute: async (_input, context) => ({\n protocolVersion: context.mcp?.protocolVersion ?? null,\n elicitation: await context\n .mcp!.elicitation.sendRequest({ message: 'x', requestedSchema: { type: 'object', properties: {} } })\n .then(\n () => 'answered',\n (error: Error) => error.message,\n ),\n }),\n }),\n interaction: createTool({\n id: 'native-fixture-interaction',\n description: 'Asks for confirmation',\n inputSchema: z.object({}),\n outputSchema: z.number(),\n suspendSchema: z.object({ phase: z.literal('confirm') }),\n resumeSchema: z.object({ confirmed: z.boolean() }),\n execute: async (_input, context) => {\n if (!context.resumeData) {\n await context.suspend?.({ phase: 'confirm' });\n return;\n }\n return 1;\n },\n }),\n },\n });\n }\n\n // Converts tools like the 1.x package does; `context.mcp` flows through CoreToolBuilder.\n convertTools(tools: ToolsInput) {\n const converted: Record<string, InternalCoreTool> = {};\n for (const [name, tool] of Object.entries(tools)) {\n converted[name] = makeCoreTool(tool, {\n name,\n requestContext: new RequestContext(),\n mastra: this.mastra,\n logger: this.logger,\n }) as InternalCoreTool;\n }\n return converted;\n }\n async executeTool(\n toolId: string,\n args: unknown,\n executionContext: Parameters<MCPServerBase['executeTool']>[2] = {},\n ): Promise<MCPToolExecutionResultV2> {\n const tool = this.convertedTools[toolId];\n if (!tool?.execute) throw new Error(`Tool ${toolId} not found`);\n let suspension: { payload: unknown } | undefined;\n const mcp = requestContext2026();\n const output = await tool.execute(args, {\n // Same idiom as the 1.x package: an empty toolCallId keeps CoreToolBuilder on the MCP path.\n toolCallId: '',\n messages: [],\n requestContext: executionContext.requestContext,\n abortSignal: mcp.extra.signal,\n mcp,\n suspend: async (payload: unknown) => void (suspension = { payload }),\n resumeData: executionContext.resumeData,\n suspendPayload: executionContext.suspendPayload,\n });\n if (suspension) {\n const original = this.originalTools[toolId];\n const resumeSchema = original && 'resumeSchema' in original ? original.resumeSchema : undefined;\n return {\n status: 'suspended',\n suspendPayload: suspension.payload,\n resumeSchema: resumeSchema ? standardSchemaToJSONSchema(resumeSchema, { io: 'input' }) : undefined,\n };\n }\n // Core reports invalid input/resume data as a validation-error output (the same\n // object agents see); a 2.x server rejects it like any other failed call.\n if (isValidationError(output)) throw new Error(output.message);\n return { status: 'completed', output };\n }\n\n async startHTTP(options: MCPServerHTTPOptions) {\n options.res.statusCode = 200;\n options.res.setHeader('Content-Type', 'application/json');\n options.res.end(JSON.stringify({ native: true, httpPath: options.httpPath }));\n }\n async startStdio() {}\n async close() {}\n getServerInfo() {\n return {\n id: this.id,\n name: this.name,\n version_detail: { version: this.version, release_date: this.releaseDate, is_latest: this.isLatest },\n };\n }\n getServerDetail() {\n return this.getServerInfo();\n }\n getToolListInfo() {\n return { tools: Object.keys(this.tools()).map(name => ({ name, inputSchema: { type: 'object' } })) };\n }\n getToolInfo(name: string) {\n return this.getToolListInfo().tools.find(tool => tool.name === name);\n }\n async readResource() {\n return { contents: [] };\n }\n async listResources() {\n return { resources: [] };\n }\n}\n","import { Mastra } from '@mastra/core/mastra';\nimport { createTool } from '@mastra/core/tools';\nimport { MCPServer, MCPClient } from '@mastra/mcp';\nimport { describe, it, expect, beforeAll, afterAll } from 'vitest';\nimport { z } from 'zod';\nimport { NativeMCPFixture } from './native-mcp-fixture';\n\n/**\n * Configuration for MCP transport test suite\n */\nexport interface MCPTransportTestConfig {\n /** Name for the test suite */\n suiteName?: string;\n /**\n * Creates an HTTP server for the given Mastra instance.\n * Returns the server and port for testing.\n */\n createServer: (mastra: Mastra) => Promise<{\n /** The HTTP server instance (will be closed in afterAll) */\n server: { close: () => void };\n /** The port the server is listening on */\n port: number;\n }>;\n}\n\n/**\n * Creates a standardized integration test suite for MCP transport routes\n *\n * Tests MCP protocol transport endpoints using MCPClient:\n * - HTTP Transport (POST /api/mcp/:serverId/mcp)\n * - Legacy SSE routes (GET /api/mcp/:serverId/sse, POST /api/mcp/:serverId/messages)\n * are only served for MCP 1.x servers; MCP 2.x instances answer 404.\n *\n * These tests require a real HTTP server because MCPClient drives the\n * self-contained 2026-07-28 request lifecycle over real Streamable HTTP.\n *\n * Usage:\n * ```ts\n * // Hono adapter\n * createMCPTransportTestSuite({\n * suiteName: 'Hono MCP Transport',\n * createServer: async (mastra) => {\n * const app = await createHonoServer(mastra, { tools: {} });\n * const server = serve({ fetch: app.fetch, port: 0 });\n * const address = server.address();\n * const port = typeof address === 'object' ? address.port : 9999;\n * return { server, port };\n * },\n * });\n *\n * // Express adapter\n * createMCPTransportTestSuite({\n * suiteName: 'Express MCP Transport',\n * createServer: async (mastra) => {\n * const app = express();\n * const adapter = new MastraServer({ mastra });\n * adapter.mount(app);\n * const server = app.listen(0);\n * const address = server.address();\n * const port = typeof address === 'object' ? address.port : 9999;\n * return { server, port };\n * },\n * });\n * ```\n */\nexport function createMCPTransportTestSuite(config: MCPTransportTestConfig) {\n const { suiteName = 'MCP Transport Routes', createServer } = config;\n\n const expectTextToolResult = (result: any, expectedPayload: unknown) => {\n expect(result).toBeDefined();\n expect(result).toMatchObject({\n isError: false,\n content: [\n {\n type: 'text',\n },\n ],\n });\n expect(result.content).toHaveLength(1);\n expect(JSON.parse(result.content[0].text)).toEqual(expectedPayload);\n };\n\n describe(suiteName, () => {\n // Test tools - no outputSchema to avoid MCP validation conflicts\n const weatherTool = createTool({\n id: 'getWeather',\n description: 'Gets the current weather for a location',\n inputSchema: z.object({\n location: z.string().describe('The location to get weather for'),\n }),\n execute: async ({ location }) => ({\n temperature: 72,\n condition: `Sunny in ${location}`,\n }),\n });\n\n const calculatorTool = createTool({\n id: 'calculate',\n description: 'Performs basic calculations',\n inputSchema: z.object({\n operation: z.enum(['add', 'subtract', 'multiply', 'divide']),\n a: z.number(),\n b: z.number(),\n }),\n execute: async ({ operation, a, b }) => {\n let result = 0;\n switch (operation) {\n case 'add':\n result = a + b;\n break;\n case 'subtract':\n result = a - b;\n break;\n case 'multiply':\n result = a * b;\n break;\n case 'divide':\n result = a / b;\n break;\n }\n return { result };\n },\n });\n\n let httpServer: { close: () => void };\n let port: number;\n let mcpServer1: MCPServer;\n let mcpServer2: MCPServer;\n let mcpClient: MCPClient;\n let mastra: Mastra;\n\n beforeAll(async () => {\n // Create MCP servers with tools\n mcpServer1 = new MCPServer({\n name: 'server1',\n version: '1.0.0',\n description: 'Test MCP Server 1',\n tools: {\n getWeather: weatherTool,\n calculate: calculatorTool,\n },\n });\n\n mcpServer2 = new MCPServer({\n name: 'server2',\n version: '1.1.0',\n description: 'Test MCP Server 2',\n tools: {},\n });\n\n // Create Mastra instance\n mastra = new Mastra({\n mcpServers: {\n 'test-server-1': mcpServer1,\n 'test-server-2': mcpServer2,\n 'native-fixture': new NativeMCPFixture(),\n },\n });\n\n // Create HTTP server using adapter-specific implementation\n const serverSetup = await createServer(mastra);\n httpServer = serverSetup.server;\n port = serverSetup.port;\n\n // Create MCPClient for transport tests\n mcpClient = new MCPClient({\n servers: {\n server1: {\n url: new URL(`http://localhost:${port}/api/mcp/${mcpServer1.id}/mcp`),\n },\n server2: {\n url: new URL(`http://localhost:${port}/api/mcp/${mcpServer2.id}/mcp`),\n },\n },\n });\n }, 30000);\n\n afterAll(async () => {\n await mcpClient?.disconnect();\n httpServer?.close();\n await mcpServer1?.close();\n await mcpServer2?.close();\n }, 30000);\n\n describe('native MCP v2 adapter dispatch', () => {\n it('dispatches HTTP through the shared adapter path', async () => {\n const response = await fetch(`http://localhost:${port}/api/mcp/native-fixture/mcp`, { method: 'POST' });\n expect(response.status).toBe(200);\n expect(await response.json()).toEqual({ native: true, httpPath: '/api/mcp/native-fixture/mcp' });\n });\n\n it.each([\n { path: 'sse', method: 'GET' },\n { path: 'messages', method: 'POST' },\n ])('rejects the legacy $path route for a native server', async ({ path, method }) => {\n const response = await fetch(`http://localhost:${port}/api/mcp/native-fixture/${path}`, { method });\n expect(response.status).toBe(404);\n });\n\n it('executes ordinary tools with the v2 request context and reports a suspended tool truthfully', async () => {\n const base = `http://localhost:${port}/api/mcp/native-fixture/tools`;\n const init = {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ data: {} }),\n };\n const ordinary = await fetch(`${base}/ordinary/execute`, init);\n expect(ordinary.status).toBe(200);\n expect(await ordinary.json()).toEqual({\n result: {\n protocolVersion: '2026-07-28',\n elicitation: 'elicitation.sendRequest is not available on a 2026-07-28 server',\n },\n });\n const suspended = await fetch(`${base}/interaction/execute`, init);\n expect(suspended.status).toBe(200);\n expect(await suspended.json()).toEqual({\n status: 'suspended',\n suspendPayload: { phase: 'confirm' },\n resumeSchema: expect.objectContaining({ type: 'object', properties: { confirmed: { type: 'boolean' } } }),\n });\n });\n\n it('continues a suspended tool over REST with resumeData and the echoed suspendPayload', async () => {\n const base = `http://localhost:${port}/api/mcp/native-fixture/tools/interaction/execute`;\n const post = (body: unknown) =>\n fetch(base, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) });\n\n const resumed = await post({ data: {}, resumeData: { confirmed: true }, suspendPayload: { phase: 'confirm' } });\n expect(resumed.status).toBe(200);\n expect(await resumed.json()).toEqual({ result: 1 });\n\n // An answer that fails resumeSchema is a failed call, never a completed one.\n const invalid = await post({\n data: {},\n resumeData: { confirmed: 'yes' },\n suspendPayload: { phase: 'confirm' },\n });\n expect(invalid.status).toBe(500);\n expect(await invalid.json()).not.toMatchObject({ status: 'completed' });\n });\n });\n\n describe('HTTP Transport (/api/mcp/:serverId/mcp)', () => {\n describe('Error handling (raw HTTP)', () => {\n it('should return 404 for non-existent server', async () => {\n const res = await fetch(`http://localhost:${port}/api/mcp/non-existent/mcp`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json, text/event-stream',\n },\n body: JSON.stringify({\n jsonrpc: '2.0',\n method: 'initialize',\n params: {\n protocolVersion: '2024-11-05',\n capabilities: {},\n clientInfo: { name: 'test-client', version: '1.0.0' },\n },\n id: 1,\n }),\n });\n\n expect(res.status).toBe(404);\n });\n });\n\n describe('Protocol operations (MCPClient)', () => {\n it('should list tools via MCPClient', async () => {\n const tools = await mcpClient.listTools();\n\n // MCPClient prefixes tool names with server name\n expect(tools['server1_getWeather']).toBeDefined();\n expect(tools['server1_calculate']).toBeDefined();\n });\n\n it('should execute tool via MCPClient', async () => {\n const tools = await mcpClient.listTools();\n const calculateTool = tools['server1_calculate'];\n\n expect(calculateTool).toBeDefined();\n if (!calculateTool) {\n throw new Error('Expected server1_calculate tool');\n }\n expect(calculateTool.execute).toBeDefined();\n\n const result = await calculateTool.execute!({ operation: 'multiply', a: 6, b: 7 }, {} as any);\n\n expectTextToolResult(result, { result: 42 });\n });\n\n it('should execute weather tool via MCPClient', async () => {\n const tools = await mcpClient.listTools();\n const weatherToolInstance = tools['server1_getWeather'];\n\n expect(weatherToolInstance).toBeDefined();\n if (!weatherToolInstance) {\n throw new Error('Expected server1_getWeather tool');\n }\n expect(weatherToolInstance.execute).toBeDefined();\n\n const result = await weatherToolInstance.execute!({ location: 'Austin' }, {} as any);\n\n expectTextToolResult(result, {\n temperature: 72,\n condition: 'Sunny in Austin',\n });\n });\n\n it('should handle multiple MCP servers', async () => {\n const tools = await mcpClient.listTools();\n\n // Server 1 has 2 tools\n expect(tools['server1_getWeather']).toBeDefined();\n expect(tools['server1_calculate']).toBeDefined();\n\n // Server 2 has 0 tools\n const server2Tools = Object.keys(tools).filter(k => k.startsWith('server2_'));\n expect(server2Tools).toHaveLength(0);\n });\n });\n\n describe('Tool execution errors (MCPClient)', () => {\n let failingClient: MCPClient;\n let failingServer: MCPServer;\n let failingMastra: Mastra;\n let failingHttpServer: { close: () => void };\n\n beforeAll(async () => {\n const failingTool = createTool({\n id: 'failingTool',\n description: 'A tool that always throws an error',\n inputSchema: z.object({}),\n execute: async () => {\n throw new Error('Tool execution failed intentionally');\n },\n });\n\n failingServer = new MCPServer({\n name: 'failingServer',\n version: '1.0.0',\n tools: { failingTool },\n });\n\n failingMastra = new Mastra({\n mcpServers: { 'failing-server': failingServer },\n });\n\n const serverSetup = await createServer(failingMastra);\n failingHttpServer = serverSetup.server;\n const failingPort = serverSetup.port;\n\n failingClient = new MCPClient({\n servers: {\n failing: {\n url: new URL(`http://localhost:${failingPort}/api/mcp/${failingServer.id}/mcp`),\n // This test asserts the shape of the server's isError envelope\n // (result.content carries the serialized error), so opt out of the\n // default throw-on-error behavior and resolve with the raw result.\n onToolError: 'return',\n },\n },\n });\n }, 30000);\n\n afterAll(async () => {\n await failingClient?.disconnect();\n failingHttpServer?.close();\n await failingServer?.close();\n }, 30000);\n\n it('should return error when tool execution fails', async () => {\n const tools = await failingClient.listTools();\n const failingTool = tools['failing_failingTool'];\n\n expect(failingTool).toBeDefined();\n if (!failingTool) {\n throw new Error('Expected failing_failingTool tool');\n }\n\n const result = await failingTool.execute!({}, {} as any);\n\n expect(result).toBeDefined();\n expect(result.content).toBeInstanceOf(Array);\n expect(result.content.length).toBeGreaterThan(0);\n\n const errorOutput = result.content[0];\n expect(errorOutput.type).toBe('text');\n\n const errorData = JSON.parse(errorOutput.text);\n expect(errorData.message).toContain('Tool execution failed intentionally');\n expect(errorData.code).toBe('TOOL_EXECUTION_FAILED');\n });\n });\n });\n\n describe('SSE Transport (/api/mcp/:serverId/sse)', () => {\n describe('Error handling (raw HTTP)', () => {\n it('should return 404 for non-existent server on GET /sse', async () => {\n const res = await fetch(`http://localhost:${port}/api/mcp/non-existent/sse`);\n expect(res.status).toBe(404);\n });\n\n it('should return 404 for non-existent server on POST /messages', async () => {\n const res = await fetch(`http://localhost:${port}/api/mcp/non-existent/messages`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n method: 'test',\n id: 1,\n }),\n });\n\n expect(res.status).toBe(404);\n });\n });\n\n describe('MCP 2.x servers (MCPClient)', () => {\n it('does not serve the legacy SSE transport for a 2.x MCPServer', async ctx => {\n if ((mcpServer1 as { mcpVersion?: number }).mcpVersion !== 2) ctx.skip();\n const res = await fetch(`http://localhost:${port}/api/mcp/${mcpServer1.id}/sse`);\n expect(res.status).toBe(404);\n\n const messages = await fetch(`http://localhost:${port}/api/mcp/${mcpServer1.id}/messages`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ jsonrpc: '2.0', method: 'tools/list', id: 1 }),\n });\n expect(messages.status).toBe(404);\n });\n\n it('fails to connect through the SSE URL without downgrading', async ctx => {\n if ((mcpServer1 as { mcpVersion?: number }).mcpVersion !== 2) ctx.skip();\n const sseClient = new MCPClient({\n id: `sse-rejection-${port}`,\n servers: {\n server1: { url: new URL(`http://localhost:${port}/api/mcp/${mcpServer1.id}/sse`) },\n },\n });\n try {\n const { tools, errors } = await sseClient.listToolsWithErrors();\n expect(tools).toEqual({});\n expect(errors.server1).toContain('Failed to connect to MCP server server1');\n } finally {\n await sseClient.disconnect();\n }\n });\n });\n });\n });\n}\n","import type { ServerRoute } from '@mastra/server/server-adapter';\nimport { describe, it, expect, beforeEach, afterEach } from 'vitest';\nimport { createDefaultTestContext } from './test-helpers';\nimport type { AdapterTestContext } from './test-helpers';\n\n/**\n * Configuration for multipart FormData test suite\n */\nexport interface MultipartTestSuiteConfig {\n /** Name for the test suite */\n suiteName?: string;\n\n /**\n * Setup adapter and app for testing\n */\n setupAdapter: (\n context: AdapterTestContext,\n options?: { bodyLimitOptions?: { maxSize: number; onError: (err: any) => any } },\n ) => { adapter: any; app: any } | Promise<{ adapter: any; app: any }>;\n\n /**\n * Start a test server and return its base URL\n * The returned cleanup function should close the server\n */\n startServer: (app: any) => Promise<{ baseUrl: string; cleanup: () => Promise<void> }>;\n\n /**\n * Register a route with the adapter\n */\n registerRoute: (adapter: any, app: any, route: ServerRoute, options?: { prefix?: string }) => Promise<void>;\n\n /**\n * Get the context middleware to use\n */\n getContextMiddleware: (adapter: any) => any;\n\n /**\n * Apply middleware to app\n */\n applyMiddleware: (app: any, middleware: any) => void;\n}\n\n/**\n * Creates a standardized test suite for multipart/form-data handling in server adapters.\n *\n * Tests:\n * - File uploads are correctly parsed to Buffers\n * - JSON fields in FormData are parsed\n * - File size limits are enforced\n * - Error handling for malformed requests\n */\nexport function createMultipartTestSuite(config: MultipartTestSuiteConfig) {\n const {\n suiteName = 'Multipart FormData Tests',\n setupAdapter,\n startServer,\n registerRoute,\n getContextMiddleware,\n applyMiddleware,\n } = config;\n\n describe(suiteName, () => {\n let context: AdapterTestContext;\n let serverInfo: { baseUrl: string; cleanup: () => Promise<void> } | null = null;\n\n beforeEach(async () => {\n context = await createDefaultTestContext();\n });\n\n afterEach(async () => {\n if (serverInfo) {\n await serverInfo.cleanup();\n serverInfo = null;\n }\n });\n\n it('should parse file uploads as Buffers', async () => {\n const { adapter, app } = await setupAdapter(context);\n\n // Track received body\n let receivedBody: any;\n\n const testRoute: ServerRoute<any, any, any> = {\n method: 'POST',\n path: '/test/upload',\n responseType: 'json',\n handler: async (params: any) => {\n receivedBody = params;\n return { success: true, hasAudio: !!params.audio };\n },\n };\n\n applyMiddleware(app, getContextMiddleware(adapter));\n await registerRoute(adapter, app, testRoute, { prefix: '' });\n\n serverInfo = await startServer(app);\n\n // Create FormData with a file\n const formData = new FormData();\n const audioContent = new Uint8Array([0x52, 0x49, 0x46, 0x46]); // RIFF header bytes\n const audioBlob = new Blob([audioContent], { type: 'audio/wav' });\n formData.append('audio', audioBlob, 'test.wav');\n\n const response = await fetch(`${serverInfo.baseUrl}/test/upload`, {\n method: 'POST',\n body: formData,\n });\n\n expect(response.status).toBe(200);\n const result = await response.json();\n expect(result).toMatchObject({ success: true, hasAudio: true });\n\n // Verify the audio was parsed as a Buffer\n expect(receivedBody.audio).toBeDefined();\n expect(Buffer.isBuffer(receivedBody.audio)).toBe(true);\n expect(receivedBody.audio.length).toBe(4);\n });\n\n it('should parse JSON string fields in FormData', async () => {\n const { adapter, app } = await setupAdapter(context);\n\n let receivedBody: any;\n\n const testRoute: ServerRoute<any, any, any> = {\n method: 'POST',\n path: '/test/upload-with-options',\n responseType: 'json',\n handler: async (params: any) => {\n receivedBody = params;\n return { success: true };\n },\n };\n\n applyMiddleware(app, getContextMiddleware(adapter));\n await registerRoute(adapter, app, testRoute, { prefix: '' });\n\n serverInfo = await startServer(app);\n\n // Create FormData with file and JSON options\n const formData = new FormData();\n const audioBlob = new Blob([new Uint8Array([1, 2, 3, 4])], { type: 'audio/wav' });\n formData.append('audio', audioBlob, 'test.wav');\n formData.append('options', JSON.stringify({ language: 'en', format: 'mp3' }));\n\n const response = await fetch(`${serverInfo.baseUrl}/test/upload-with-options`, {\n method: 'POST',\n body: formData,\n });\n\n expect(response.status).toBe(200);\n\n // Verify options was parsed as object, not string\n expect(receivedBody.options).toBeDefined();\n expect(typeof receivedBody.options).toBe('object');\n expect(receivedBody.options.language).toBe('en');\n expect(receivedBody.options.format).toBe('mp3');\n });\n\n it('should handle plain string fields in FormData', async () => {\n const { adapter, app } = await setupAdapter(context);\n\n let receivedBody: any;\n\n const testRoute: ServerRoute<any, any, any> = {\n method: 'POST',\n path: '/test/upload-with-string',\n responseType: 'json',\n handler: async (params: any) => {\n receivedBody = params;\n return { success: true };\n },\n };\n\n applyMiddleware(app, getContextMiddleware(adapter));\n await registerRoute(adapter, app, testRoute, { prefix: '' });\n\n serverInfo = await startServer(app);\n\n // Create FormData with file and plain string field\n const formData = new FormData();\n const audioBlob = new Blob([new Uint8Array([1, 2, 3, 4])], { type: 'audio/wav' });\n formData.append('audio', audioBlob, 'test.wav');\n formData.append('name', 'test-recording');\n\n const response = await fetch(`${serverInfo.baseUrl}/test/upload-with-string`, {\n method: 'POST',\n body: formData,\n });\n\n expect(response.status).toBe(200);\n\n // Verify name remains a string (not parsed as JSON)\n expect(receivedBody.name).toBe('test-recording');\n });\n\n it('should reject files exceeding size limit', async () => {\n const maxSize = 100; // 100 bytes limit\n const { adapter, app } = await setupAdapter(context, {\n bodyLimitOptions: {\n maxSize,\n onError: (err: any) => ({ error: 'File too large' }),\n },\n });\n\n const testRoute: ServerRoute<any, any, any> = {\n method: 'POST',\n path: '/test/upload-limited',\n responseType: 'json',\n handler: async () => {\n return { success: true };\n },\n };\n\n applyMiddleware(app, getContextMiddleware(adapter));\n await registerRoute(adapter, app, testRoute, { prefix: '' });\n\n serverInfo = await startServer(app);\n\n // Create FormData with a file larger than the limit\n const formData = new FormData();\n const largeContent = new Uint8Array(200); // 200 bytes, exceeds 100 byte limit\n const largeBlob = new Blob([largeContent], { type: 'audio/wav' });\n formData.append('audio', largeBlob, 'large.wav');\n\n const response = await fetch(`${serverInfo.baseUrl}/test/upload-limited`, {\n method: 'POST',\n body: formData,\n });\n\n // Should return error status (413 or 500 depending on implementation)\n expect(response.status).toBeGreaterThanOrEqual(400);\n });\n\n it('should handle empty FormData gracefully', async () => {\n const { adapter, app } = await setupAdapter(context);\n\n let receivedBody: any;\n\n const testRoute: ServerRoute<any, any, any> = {\n method: 'POST',\n path: '/test/upload-empty',\n responseType: 'json',\n handler: async (params: any) => {\n receivedBody = params;\n return {\n success: true,\n // Filter out all system-injected params to get only body fields\n bodyKeys: Object.keys(params).filter(\n k =>\n ![\n 'mastra',\n 'requestContext',\n 'tools',\n 'taskStore',\n 'abortSignal',\n 'registeredTools',\n 'routePrefix',\n 'request',\n ].includes(k),\n ),\n };\n },\n };\n\n applyMiddleware(app, getContextMiddleware(adapter));\n await registerRoute(adapter, app, testRoute, { prefix: '' });\n\n serverInfo = await startServer(app);\n\n // Create empty FormData\n const formData = new FormData();\n\n const response = await fetch(`${serverInfo.baseUrl}/test/upload-empty`, {\n method: 'POST',\n body: formData,\n });\n\n expect(response.status).toBe(200);\n const result = await response.json();\n expect(result).toMatchObject({ success: true, bodyKeys: [] });\n });\n\n it('should handle multiple files', async () => {\n const { adapter, app } = await setupAdapter(context);\n\n let receivedBody: any;\n\n const testRoute: ServerRoute<any, any, any> = {\n method: 'POST',\n path: '/test/upload-multiple',\n responseType: 'json',\n handler: async (params: any) => {\n receivedBody = params;\n return {\n success: true,\n hasFile1: !!params.file1,\n hasFile2: !!params.file2,\n };\n },\n };\n\n applyMiddleware(app, getContextMiddleware(adapter));\n await registerRoute(adapter, app, testRoute, { prefix: '' });\n\n serverInfo = await startServer(app);\n\n // Create FormData with multiple files\n const formData = new FormData();\n const file1 = new Blob([new Uint8Array([1, 2, 3])], { type: 'audio/wav' });\n const file2 = new Blob([new Uint8Array([4, 5, 6])], { type: 'audio/wav' });\n formData.append('file1', file1, 'file1.wav');\n formData.append('file2', file2, 'file2.wav');\n\n const response = await fetch(`${serverInfo.baseUrl}/test/upload-multiple`, {\n method: 'POST',\n body: formData,\n });\n\n expect(response.status).toBe(200);\n const result = await response.json();\n expect(result).toMatchObject({ hasFile1: true, hasFile2: true });\n\n // Verify both files were parsed\n expect(Buffer.isBuffer(receivedBody.file1)).toBe(true);\n expect(Buffer.isBuffer(receivedBody.file2)).toBe(true);\n });\n\n it('should still handle JSON requests normally', async () => {\n const { adapter, app } = await setupAdapter(context);\n\n let receivedBody: any;\n\n const testRoute: ServerRoute<any, any, any> = {\n method: 'POST',\n path: '/test/json',\n responseType: 'json',\n handler: async (params: any) => {\n receivedBody = params;\n return { success: true, message: params.message };\n },\n };\n\n applyMiddleware(app, getContextMiddleware(adapter));\n await registerRoute(adapter, app, testRoute, { prefix: '' });\n\n serverInfo = await startServer(app);\n\n const response = await fetch(`${serverInfo.baseUrl}/test/json`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ message: 'Hello, World!' }),\n });\n\n expect(response.status).toBe(200);\n const result = await response.json();\n expect(result).toMatchObject({ success: true, message: 'Hello, World!' });\n });\n\n it('should ignore form fields named with special object keys', async () => {\n const { adapter, app } = await setupAdapter(context);\n\n const testRoute: ServerRoute<any, any, any> = {\n method: 'POST',\n path: '/test/upload-special-keys',\n responseType: 'json',\n handler: async (params: any) => {\n return {\n success: true,\n name: params.name ?? null,\n options: params.options ?? null,\n // Any of these becoming truthy means a special-key field leaked into the body\n inheritedIsAdmin: params.isAdmin ?? null,\n bodyKeys: Object.keys(params).filter(\n k =>\n ![\n 'mastra',\n 'requestContext',\n 'tools',\n 'taskStore',\n 'abortSignal',\n 'registeredTools',\n 'routePrefix',\n 'request',\n ].includes(k),\n ),\n };\n },\n };\n\n applyMiddleware(app, getContextMiddleware(adapter));\n await registerRoute(adapter, app, testRoute, { prefix: '' });\n\n serverInfo = await startServer(app);\n\n const formData = new FormData();\n // Field names that must never be written onto the parsed body object\n formData.append('__proto__', JSON.stringify({ isAdmin: true }));\n formData.append('constructor', JSON.stringify({ prototype: { isAdmin: true } }));\n const fileBlob = new Blob([new Uint8Array([1, 2, 3])], { type: 'application/octet-stream' });\n formData.append('prototype', fileBlob, 'payload.bin');\n // Legitimate fields alongside them\n formData.append('name', 'legit-recording');\n formData.append('options', JSON.stringify({ language: 'en' }));\n\n const response = await fetch(`${serverInfo.baseUrl}/test/upload-special-keys`, {\n method: 'POST',\n body: formData,\n });\n\n expect(response.status).toBe(200);\n const result: any = await response.json();\n expect(result.name).toBe('legit-recording');\n expect(result.options).toMatchObject({ language: 'en' });\n expect(result.inheritedIsAdmin).toBeNull();\n expect(result.bodyKeys).not.toContain('__proto__');\n expect(result.bodyKeys).not.toContain('constructor');\n expect(result.bodyKeys).not.toContain('prototype');\n // The process-wide Object.prototype must be untouched\n expect(({} as any).isAdmin).toBeUndefined();\n });\n });\n}\n","import { Mastra } from '@mastra/core/mastra';\nimport { describe, it, expect, beforeEach, vi } from 'vitest';\nimport type { AdapterTestContext } from './test-helpers';\nimport { createDefaultTestContext } from './test-helpers';\n\n/**\n * Configuration for HTTP logging test suite\n */\nexport interface HttpLoggingTestSuiteConfig<TApp> {\n /** Name for the test suite */\n suiteName?: string;\n\n /**\n * Setup adapter with given Mastra instance\n */\n setupAdapter: (app: TApp, mastra: Mastra) => { adapter: any; app: TApp } | Promise<{ adapter: any; app: TApp }>;\n\n /**\n * Create a new app instance\n */\n createApp: () => TApp;\n\n /**\n * Register a route handler for testing\n * Returns a function to register the route (called after init for some adapters)\n */\n addRoute: (\n app: TApp,\n method: 'GET' | 'POST' | 'PUT' | 'DELETE',\n path: string,\n handler: (req: any) => any | Promise<any>,\n ) => void | Promise<void>;\n\n /**\n * Execute an HTTP request against the app\n */\n executeRequest: (\n app: TApp,\n method: string,\n url: string,\n options?: { headers?: Record<string, string>; body?: string },\n ) => Promise<{ status: number }>;\n}\n\n/**\n * Creates a standardized test suite for HTTP logging across all server adapters.\n *\n * Tests:\n * - Disabled logging (no logs when apiReqLogs is false)\n * - Default logging (info level with basic fields)\n * - Custom log levels (debug, info, warn)\n * - Path exclusion (health checks, metrics)\n * - Query parameter inclusion\n * - Header inclusion\n * - Sensitive header redaction (default and custom)\n * - Different HTTP methods (GET, POST, PUT, DELETE)\n * - Error status codes (404, 500)\n */\nexport function createHttpLoggingTestSuite<TApp>(config: HttpLoggingTestSuiteConfig<TApp>) {\n const { suiteName = 'HTTP Logging', setupAdapter, createApp, addRoute, executeRequest } = config;\n\n describe(suiteName, () => {\n let app: TApp;\n let logSpy: ReturnType<typeof vi.spyOn>;\n\n beforeEach(() => {\n app = createApp();\n vi.clearAllMocks();\n });\n\n it('should not log when apiReqLogs is disabled', async () => {\n const mastra = new Mastra({});\n const { adapter } = await setupAdapter(app, mastra);\n\n logSpy = vi.spyOn(adapter.logger, 'info');\n\n await adapter.init();\n\n await addRoute(app, 'GET', '/test', () => ({ message: 'success' }));\n\n await executeRequest(app, 'GET', 'http://localhost/test');\n\n expect(logSpy).not.toHaveBeenCalled();\n });\n\n it('should log HTTP requests when enabled with default config', async () => {\n const mastra = new Mastra({\n server: {\n build: {\n apiReqLogs: true,\n },\n },\n });\n const { adapter } = await setupAdapter(app, mastra);\n\n logSpy = vi.spyOn(adapter.logger, 'info');\n\n await adapter.init();\n\n await addRoute(app, 'GET', '/test', () => ({ message: 'success' }));\n\n const response = await executeRequest(app, 'GET', 'http://localhost/test');\n\n expect(response.status).toBe(200);\n expect(logSpy).toHaveBeenCalledWith(\n expect.stringMatching(/GET \\/test 200 \\d+ms/),\n expect.objectContaining({\n method: 'GET',\n path: '/test',\n status: 200,\n duration: expect.stringMatching(/\\d+ms/),\n }),\n );\n });\n\n it('should use custom log level', async () => {\n const mastra = new Mastra({\n server: {\n build: {\n apiReqLogs: {\n enabled: true,\n level: 'debug',\n },\n },\n },\n });\n const { adapter } = await setupAdapter(app, mastra);\n\n const debugSpy = vi.spyOn(adapter.logger, 'debug');\n\n await adapter.init();\n\n await addRoute(app, 'GET', '/test', () => ({ message: 'success' }));\n\n await executeRequest(app, 'GET', 'http://localhost/test');\n\n expect(debugSpy).toHaveBeenCalledWith(expect.stringMatching(/GET \\/test 200 \\d+ms/), expect.any(Object));\n });\n\n it('should exclude paths from logging', async () => {\n const mastra = new Mastra({\n server: {\n build: {\n apiReqLogs: {\n enabled: true,\n excludePaths: ['/health', '/ready'],\n },\n },\n },\n });\n const { adapter } = await setupAdapter(app, mastra);\n\n logSpy = vi.spyOn(adapter.logger, 'info');\n\n await adapter.init();\n\n await addRoute(app, 'GET', '/health', () => ({ status: 'ok' }));\n await addRoute(app, 'GET', '/test', () => ({ message: 'success' }));\n\n await executeRequest(app, 'GET', 'http://localhost/health');\n await executeRequest(app, 'GET', 'http://localhost/test');\n\n expect(logSpy).toHaveBeenCalledTimes(1);\n expect(logSpy).toHaveBeenCalledWith(expect.stringMatching(/GET \\/test 200/), expect.any(Object));\n });\n\n it('should include query params when configured', async () => {\n const mastra = new Mastra({\n server: {\n build: {\n apiReqLogs: {\n enabled: true,\n includeQueryParams: true,\n },\n },\n },\n });\n const { adapter } = await setupAdapter(app, mastra);\n\n logSpy = vi.spyOn(adapter.logger, 'info');\n\n await adapter.init();\n\n await addRoute(app, 'GET', '/test', () => ({ message: 'success' }));\n\n await executeRequest(app, 'GET', 'http://localhost/test?foo=bar&baz=qux');\n\n expect(logSpy).toHaveBeenCalledWith(\n expect.any(String),\n expect.objectContaining({\n query: expect.objectContaining({\n foo: 'bar',\n baz: 'qux',\n }),\n }),\n );\n });\n\n it('should include headers when configured', async () => {\n const mastra = new Mastra({\n server: {\n build: {\n apiReqLogs: {\n enabled: true,\n includeHeaders: true,\n },\n },\n },\n });\n const { adapter } = await setupAdapter(app, mastra);\n\n logSpy = vi.spyOn(adapter.logger, 'info');\n\n await adapter.init();\n\n await addRoute(app, 'GET', '/test', () => ({ message: 'success' }));\n\n await executeRequest(app, 'GET', 'http://localhost/test', {\n headers: {\n 'x-custom-header': 'custom-value',\n 'user-agent': 'test-client',\n },\n });\n\n expect(logSpy).toHaveBeenCalledWith(\n expect.any(String),\n expect.objectContaining({\n headers: expect.objectContaining({\n 'x-custom-header': 'custom-value',\n 'user-agent': 'test-client',\n }),\n }),\n );\n });\n\n it('should redact sensitive headers by default', async () => {\n const mastra = new Mastra({\n server: {\n build: {\n apiReqLogs: {\n enabled: true,\n includeHeaders: true,\n },\n },\n },\n });\n const { adapter } = await setupAdapter(app, mastra);\n\n logSpy = vi.spyOn(adapter.logger, 'info');\n\n await adapter.init();\n\n await addRoute(app, 'GET', '/test', () => ({ message: 'success' }));\n\n await executeRequest(app, 'GET', 'http://localhost/test', {\n headers: {\n authorization: 'Bearer secret-token',\n cookie: 'session=secret-session',\n 'x-custom': 'not-sensitive',\n },\n });\n\n expect(logSpy).toHaveBeenCalledWith(\n expect.any(String),\n expect.objectContaining({\n headers: expect.objectContaining({\n authorization: '[REDACTED]',\n cookie: '[REDACTED]',\n 'x-custom': 'not-sensitive',\n }),\n }),\n );\n });\n\n it('should support custom redactHeaders', async () => {\n const mastra = new Mastra({\n server: {\n build: {\n apiReqLogs: {\n enabled: true,\n includeHeaders: true,\n redactHeaders: ['x-api-key', 'x-secret'],\n },\n },\n },\n });\n const { adapter } = await setupAdapter(app, mastra);\n\n logSpy = vi.spyOn(adapter.logger, 'info');\n\n await adapter.init();\n\n await addRoute(app, 'GET', '/test', () => ({ message: 'success' }));\n\n await executeRequest(app, 'GET', 'http://localhost/test', {\n headers: {\n 'x-api-key': 'secret-key',\n 'x-secret': 'secret-value',\n authorization: 'Bearer token',\n },\n });\n\n expect(logSpy).toHaveBeenCalledWith(\n expect.any(String),\n expect.objectContaining({\n headers: expect.objectContaining({\n 'x-api-key': '[REDACTED]',\n 'x-secret': '[REDACTED]',\n authorization: '[REDACTED]', // Defaults are always merged with custom redact list\n }),\n }),\n );\n });\n\n it('should log different HTTP methods', async () => {\n const mastra = new Mastra({\n server: {\n build: {\n apiReqLogs: true,\n },\n },\n });\n const { adapter } = await setupAdapter(app, mastra);\n\n logSpy = vi.spyOn(adapter.logger, 'info');\n\n await adapter.init();\n\n await addRoute(app, 'GET', '/test', () => ({ message: 'get' }));\n await addRoute(app, 'POST', '/test', () => ({ message: 'post' }));\n await addRoute(app, 'PUT', '/test', () => ({ message: 'put' }));\n await addRoute(app, 'DELETE', '/test', () => ({ message: 'delete' }));\n\n await executeRequest(app, 'GET', 'http://localhost/test');\n await executeRequest(app, 'POST', 'http://localhost/test', { body: '{}' });\n await executeRequest(app, 'PUT', 'http://localhost/test', { body: '{}' });\n await executeRequest(app, 'DELETE', 'http://localhost/test');\n\n expect(logSpy).toHaveBeenCalledTimes(4);\n expect(logSpy).toHaveBeenCalledWith(expect.stringMatching(/GET \\/test 200/), expect.any(Object));\n expect(logSpy).toHaveBeenCalledWith(expect.stringMatching(/POST \\/test 200/), expect.any(Object));\n expect(logSpy).toHaveBeenCalledWith(expect.stringMatching(/PUT \\/test 200/), expect.any(Object));\n expect(logSpy).toHaveBeenCalledWith(expect.stringMatching(/DELETE \\/test 200/), expect.any(Object));\n });\n\n it('should log error status codes', async () => {\n const mastra = new Mastra({\n server: {\n build: {\n apiReqLogs: true,\n },\n },\n });\n const { adapter } = await setupAdapter(app, mastra);\n\n logSpy = vi.spyOn(adapter.logger, 'info');\n\n await adapter.init();\n\n await addRoute(app, 'GET', '/not-found', () => ({ status: 404, body: { error: 'Not found' } }));\n await addRoute(app, 'GET', '/error', () => ({ status: 500, body: { error: 'Internal error' } }));\n\n await executeRequest(app, 'GET', 'http://localhost/not-found');\n await executeRequest(app, 'GET', 'http://localhost/error');\n\n expect(logSpy).toHaveBeenCalledWith(expect.stringMatching(/GET \\/not-found 404/), expect.any(Object));\n expect(logSpy).toHaveBeenCalledWith(expect.stringMatching(/GET \\/error 500/), expect.any(Object));\n });\n });\n}\n","import { Mastra } from '@mastra/core/mastra';\nimport type { BodyLimitOptions, ServerRoute } from '@mastra/server/server-adapter';\nimport { describe, it, expect } from 'vitest';\n\n/**\n * Configuration for the body-limit test suite\n */\nexport interface BodyLimitTestSuiteConfig<TApp> {\n /** Name for the test suite */\n suiteName?: string;\n\n /** Body size limit (in bytes) to configure the adapter with. Defaults to 100. */\n maxSize?: number;\n\n /** Create a new app instance */\n createApp: () => TApp;\n\n /**\n * Construct the adapter for the given app/Mastra instance with the provided\n * bodyLimitOptions, wiring up any context middleware the adapter needs.\n */\n setupAdapter: (\n app: TApp,\n mastra: Mastra,\n bodyLimitOptions?: BodyLimitOptions,\n ) => { adapter: any; app: TApp } | Promise<{ adapter: any; app: TApp }>;\n\n /** Register the given ServerRoute on the app through the adapter's registerRoute() */\n registerRoute: (adapter: any, app: TApp, route: ServerRoute<any, any, any>) => void | Promise<void>;\n\n /** Execute an HTTP request against the app and return its status code */\n executeRequest: (\n app: TApp,\n method: string,\n url: string,\n options?: { headers?: Record<string, string>; body?: string },\n ) => Promise<{ status: number }>;\n\n /** Execute a request whose transport does not add Content-Length. */\n executeRequestWithoutContentLength?: (\n app: TApp,\n method: string,\n url: string,\n options?: { headers?: Record<string, string>; body?: string },\n ) => Promise<{ status: number }>;\n\n /** Optional teardown for the app instance (e.g. closing a listening server) */\n cleanupApp?: (app: TApp) => void | Promise<void>;\n}\n\n/**\n * Creates a standardized body-limit test suite for server adapters.\n *\n * Exercises the adapter's registerRoute() body-limit gate (bodyLimitOptions.maxSize)\n * for both POST and DELETE. DELETE is included alongside the long-established POST\n * behavior as regression coverage: DELETE requests previously bypassed the body-limit\n * check entirely, even though the adapters' getParams() reads and JSON-parses the\n * request body for DELETE the same way it does for POST/PUT/PATCH.\n */\nexport function createBodyLimitTestSuite<TApp>(config: BodyLimitTestSuiteConfig<TApp>) {\n const {\n suiteName = 'Body Size Limit',\n maxSize = 100,\n createApp,\n setupAdapter,\n registerRoute,\n executeRequest,\n executeRequestWithoutContentLength,\n cleanupApp,\n } = config;\n\n describe(suiteName, () => {\n const oversizedPayload = JSON.stringify({ padding: 'x'.repeat(maxSize * 4) });\n\n it('enforces a route-specific limit without global body limit options', async () => {\n const mastra = new Mastra({});\n const app = createApp();\n const { adapter, app: wiredApp } = await setupAdapter(app, mastra);\n let handlerCalled = false;\n\n const testRoute: ServerRoute<any, any, any> = {\n method: 'POST',\n path: '/test/route-body-limit',\n responseType: 'json',\n maxBodySize: maxSize,\n handler: async ({ body }) => {\n handlerCalled = true;\n return { receivedBody: body };\n },\n };\n\n await registerRoute(adapter, wiredApp, testRoute);\n\n const response = await executeRequest(wiredApp, 'POST', 'http://localhost/test/route-body-limit', {\n headers: { 'Content-Type': 'application/json' },\n body: oversizedPayload,\n });\n\n expect(response.status).toBe(413);\n expect(handlerCalled).toBe(false);\n\n await cleanupApp?.(wiredApp);\n });\n\n if (executeRequestWithoutContentLength) {\n it('rejects an oversized route body without Content-Length before handler execution', async () => {\n const mastra = new Mastra({});\n const app = createApp();\n const { adapter, app: wiredApp } = await setupAdapter(app, mastra);\n let handlerCalled = false;\n\n const testRoute: ServerRoute<any, any, any> = {\n method: 'POST',\n path: '/test/route-body-limit-no-content-length',\n responseType: 'json',\n maxBodySize: maxSize,\n handler: async ({ body }) => {\n handlerCalled = true;\n return { receivedBody: body };\n },\n };\n\n await registerRoute(adapter, wiredApp, testRoute);\n\n const response = await executeRequestWithoutContentLength(\n wiredApp,\n 'POST',\n 'http://localhost/test/route-body-limit-no-content-length',\n {\n headers: { 'Content-Type': 'application/json' },\n body: oversizedPayload,\n },\n );\n\n expect(response.status).toBe(413);\n expect(handlerCalled).toBe(false);\n\n await cleanupApp?.(wiredApp);\n });\n }\n\n it.each(['POST', 'DELETE'] as const)('rejects an oversized %s body with 413', async method => {\n const mastra = new Mastra({});\n const app = createApp();\n const { adapter, app: wiredApp } = await setupAdapter(app, mastra, {\n maxSize,\n onError: () => ({ error: 'Request body too large' }),\n });\n\n const testRoute: ServerRoute<any, any, any> = {\n method,\n path: '/test/body-limit',\n responseType: 'json',\n handler: async ({ body }) => ({ receivedBody: body }),\n };\n\n await registerRoute(adapter, wiredApp, testRoute);\n\n const response = await executeRequest(wiredApp, method, 'http://localhost/test/body-limit', {\n headers: { 'Content-Type': 'application/json' },\n body: oversizedPayload,\n });\n\n expect(response.status).toBe(413);\n\n await cleanupApp?.(wiredApp);\n });\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["z","z3","Mastra","z","Mastra","Mastra","Mastra"],"sources":["../src/route-test-utils.ts","../src/route-test-suite.ts","../src/test-helpers.ts","../src/route-adapter-test-suite.ts","../src/mcp-route-test-suite.ts","../src/native-mcp-fixture.ts","../src/mcp-transport-test-suite.ts","../src/multipart-test-suite.ts","../src/http-logging-test-suite.ts","../src/body-limit-test-suite.ts"],"sourcesContent":["import { getZodTypeName, getZodDef } from '@mastra/core/utils';\nimport type { ServerRoute } from '@mastra/server/server-adapter';\nimport type { z, ZodSchema } from 'zod';\n\n/**\n * Normalizes a route path to ensure consistent formatting.\n * - Removes leading/trailing whitespace\n * - Validates no path traversal (..), query strings (?), or fragments (#)\n * - Collapses multiple consecutive slashes\n * - Removes trailing slashes\n * - Ensures leading slash (unless empty)\n *\n * @param path - The route path to normalize\n * @returns The normalized path (empty string for root paths)\n * @throws Error if path contains invalid characters\n */\nexport function normalizeRoutePath(path: string): string {\n let normalized = path.trim();\n if (normalized.includes('..') || normalized.includes('?') || normalized.includes('#')) {\n throw new Error(`Invalid route path: \"${path}\". Path cannot contain '..', '?', or '#'`);\n }\n normalized = normalized.replace(/\\/+/g, '/');\n if (normalized === '/' || normalized === '') {\n return '';\n }\n if (normalized.endsWith('/')) {\n normalized = normalized.slice(0, -1);\n }\n if (!normalized.startsWith('/')) {\n normalized = `/${normalized}`;\n }\n return normalized;\n}\n\n/**\n * Provide valid schema values for routes whose fields have cross-field constraints.\n */\nexport function getRouteSpecificSchemaDefaults(route: ServerRoute): {\n query?: Record<string, unknown>;\n body?: Record<string, unknown>;\n} {\n if (route.path === '/observability/traces/query/values') {\n return { body: { predicateScope: 'trace', path: 'entityName' } };\n }\n\n if (route.path === '/agent-controller/:controllerId/sessions' && route.method === 'POST') {\n return { body: { resourceId: 'test-resource' } };\n }\n\n if (route.path === '/datasets/:datasetId/compare') {\n return { body: { experimentIds: ['test-experiment-a', 'test-experiment-b'], baselineId: 'test-experiment-a' } };\n }\n\n return {};\n}\n\n/**\n * Generate context-aware test value based on field name\n */\nexport function generateContextualValue(fieldName?: string): string {\n if (!fieldName) return 'test-string';\n\n const field = fieldName.toLowerCase();\n\n // Timestamp fields used in body validation need a valid ISO string.\n if (field === 'createdat' || field === 'updatedat') return new Date().toISOString();\n\n if (field === 'entitytype') return 'AGENT';\n if (field === 'entityid') return 'test-agent';\n if (field === 'role') return 'user';\n // Cron fields must be a valid cron expression (schedule create routes).\n if (field === 'cron') return '* * * * *';\n if (field === 'fields') return 'result'; // For workflow execution result field filtering (status is always included)\n // JSON-encoded query params (wrapped with wrapSchemaForQueryParams)\n if (field === 'tags') return '[\"test-tag\"]'; // For observability traces filtering\n\n // Email fields need valid email format\n if (field === 'email' || field.includes('email')) return 'test@example.com';\n\n // Version comparison query params (from/to are version IDs)\n // Both use the same known version ID - comparing a version to itself returns empty diffs,\n // which is valid for route integration tests that verify the endpoint responds correctly\n if (field === 'from') return 'test-version-id';\n if (field === 'to') return 'test-version-id';\n\n // Workspace filesystem - content and query fields\n if (field === 'content') return 'test content'; // For write/index operations\n if (field === 'query') return 'test'; // For search operations\n\n if (field.includes('agent')) return 'test-agent';\n if (field.includes('workflow')) return 'test-workflow';\n if (field.includes('tool') && field.includes('slug')) return 'test-tool-slug';\n if (field.includes('tool')) return 'test-tool';\n if (field.includes('skill')) return 'test-skill';\n if (field.includes('reference') && field.includes('path')) return 'test-reference.md';\n if (field.includes('thread')) return 'test-thread';\n if (field === 'conversationid') return 'test-thread';\n if (field.includes('resource')) return 'test-resource';\n if (field.includes('run')) return 'test-run';\n if (field.includes('step')) return 'test-step';\n if (field.includes('task')) return 'test-task';\n if (field.includes('scorer') || field.includes('score')) return 'test-scorer';\n if (field.includes('processor')) return 'test-processor';\n if (field.includes('trace')) return 'test-trace';\n if (field.includes('span')) return 'test-span';\n if (field.includes('vector')) return 'test-vector';\n if (field.includes('index')) return 'test-index';\n if (field.includes('message')) return 'test-message';\n if (field === 'responseid') return 'test-response';\n if (field.includes('transport')) return 'test-transport';\n if (field === 'reorderedmodelids') return 'id1';\n if (field.includes('model')) return 'openai/gpt-4o';\n if (field.includes('action')) return 'merge-template';\n if (field.includes('entity')) return 'test-entity';\n if (field.includes('provider')) return 'test-provider';\n if (field.includes('dataset') && field.includes('version')) return '1';\n if (field.includes('dataset')) return 'test-dataset';\n if (field.includes('item')) return 'test-item';\n if (field.includes('experiment')) return 'test-experiment';\n if (field.includes('mcp') && field.includes('client')) return 'test-mcp-client';\n if (field.includes('prompt') && field.includes('block')) return 'test-prompt-block';\n if (field.includes('block')) return 'test-prompt-block';\n if (field === 'uri') return 'ui://test/app';\n\n return 'test-string';\n}\n\n/**\n * Generate valid test data from a Zod schema\n */\nexport function generateValidDataFromSchema(schema: z.ZodTypeAny, fieldName?: string): any {\n let typeName = getZodTypeName(schema);\n let def = getZodDef(schema);\n\n // Unwrap effects first\n while (typeName === 'ZodEffects') {\n schema = def.schema;\n typeName = getZodTypeName(schema);\n def = getZodDef(schema);\n }\n\n // Unwrap z.preprocess / .transform pipes (Zod 4 represents these as ZodPipe\n // with the validated schema at `def.out`). Without this the generator falls\n // through to `undefined` for any query schema that uses a top-level\n // preprocess (e.g. legacy-shape back-compat shims).\n while (typeName === 'ZodPipe' && def?.out) {\n schema = getZodTypeName(def.out) === 'ZodTransform' ? def.in : def.out;\n typeName = getZodTypeName(schema);\n def = getZodDef(schema);\n }\n\n if (typeName === 'ZodOptional' || typeName === 'ZodNullable') {\n return generateValidDataFromSchema(def.innerType, fieldName);\n }\n if (typeName === 'ZodDefault') {\n if ('_zod' in schema) {\n return def.defaultValue;\n } else {\n return def.defaultValue();\n }\n }\n\n if (typeName === 'ZodString') {\n const hasDateTimeFormat = (def.checks ?? []).some((check: any) => {\n const checkDef = check._zod?.def ?? check.def ?? check;\n return check.kind === 'datetime' || check.format === 'datetime' || checkDef.format === 'datetime';\n });\n if (hasDateTimeFormat) {\n if (fieldName?.toLowerCase() === 'from') return '2026-01-01T00:00:00.000Z';\n if (fieldName?.toLowerCase() === 'to') return '2026-01-02T00:00:00.000Z';\n return '2026-01-01T00:00:00.000Z';\n }\n return generateContextualValue(fieldName);\n }\n if (typeName === 'ZodNumber') {\n // Respect min/max constraints from Zod checks\n let min = -Infinity;\n let max = Infinity;\n let minInclusive = true;\n let maxInclusive = true;\n let requiresInt = false;\n let requiresSafeInt = false;\n let multipleOf: number | undefined;\n const checks = def.checks ?? [];\n for (const check of checks) {\n // Zod 3: check.kind === 'min'/'max', check.value\n if (check.kind === 'min') {\n min = check.value;\n minInclusive = check.inclusive ?? true;\n }\n if (check.kind === 'max') {\n max = check.value;\n maxInclusive = check.inclusive ?? true;\n }\n if (check.kind === 'int') requiresInt = true;\n if (check.kind === 'multipleOf') multipleOf = check.value;\n // Zod 4: checks have _zod.def with check type and value\n const zod4Def = check._zod?.def;\n if (zod4Def) {\n if (zod4Def.check === 'greater_than') {\n min = zod4Def.value;\n minInclusive = false;\n }\n if (zod4Def.check === 'greater_than_or_equal') {\n min = zod4Def.value;\n minInclusive = true;\n }\n if (zod4Def.check === 'less_than') {\n max = zod4Def.value;\n maxInclusive = false;\n }\n if (zod4Def.check === 'less_than_or_equal') {\n max = zod4Def.value;\n maxInclusive = true;\n }\n if (zod4Def.check === 'multiple_of') multipleOf = zod4Def.value;\n if (zod4Def.check === 'integer') requiresInt = true;\n if (zod4Def.check === 'safeint') {\n requiresSafeInt = true;\n requiresInt = true;\n }\n // Zod 4 emits `int()` as `number_format` with `format: 'int' | 'safeint'`.\n if (zod4Def.check === 'number_format') {\n if (zod4Def.format === 'int' || zod4Def.format === 'safeint') {\n requiresInt = true;\n if (zod4Def.format === 'safeint') requiresSafeInt = true;\n }\n }\n }\n }\n\n const step = requiresInt || requiresSafeInt ? 1 : 0.1;\n const effectiveMin = min === -Infinity ? min : minInclusive ? min : min + step;\n const effectiveMax = max === Infinity ? max : maxInclusive ? max : max - step;\n\n const clampToRange = (value: number): number => {\n if (effectiveMin !== -Infinity && value < effectiveMin) return effectiveMin;\n if (effectiveMax !== Infinity && value > effectiveMax) return effectiveMax;\n return value;\n };\n\n let candidate: number;\n if (effectiveMin !== -Infinity && effectiveMax !== Infinity) {\n candidate = (effectiveMin + effectiveMax) / 2;\n } else if (effectiveMin !== -Infinity) {\n candidate = effectiveMin;\n } else if (effectiveMax !== Infinity) {\n candidate = effectiveMax;\n } else {\n candidate = requiresInt ? 10 : 10.5;\n }\n\n candidate = clampToRange(candidate);\n\n if (multipleOf && multipleOf > 0) {\n const minBase = effectiveMin !== -Infinity ? effectiveMin : 0;\n const maxBase = effectiveMax !== Infinity ? effectiveMax : minBase + multipleOf * 10;\n let aligned = Math.ceil(minBase / multipleOf) * multipleOf;\n if (effectiveMin !== -Infinity && aligned < effectiveMin) {\n aligned += multipleOf;\n }\n if (effectiveMax !== Infinity && aligned > effectiveMax) {\n aligned = Math.floor(maxBase / multipleOf) * multipleOf;\n }\n candidate = aligned;\n }\n\n if (requiresInt) {\n candidate = Math.round(candidate);\n candidate = clampToRange(candidate);\n }\n\n if (requiresSafeInt) {\n candidate = Math.min(Math.max(candidate, Number.MIN_SAFE_INTEGER), Number.MAX_SAFE_INTEGER);\n }\n\n return candidate;\n }\n if (typeName === 'ZodBoolean') return true;\n if (typeName === 'ZodNull') return null;\n if (typeName === 'ZodUndefined') return undefined;\n if (typeName === 'ZodDate') return new Date();\n if (typeName === 'ZodBigInt') return BigInt(0);\n\n if (typeName === 'ZodLiteral') {\n if ('_zod' in schema) {\n return def.values?.[0];\n } else {\n return def.value;\n }\n }\n\n if (typeName === 'ZodEnum') {\n if ('_zod' in schema) {\n return Object.values(def.entries)[0];\n } else {\n return def.values[0];\n }\n }\n if (typeName === 'ZodNativeEnum') {\n const values = Object.values(def.values);\n return values[0];\n }\n\n if (typeName === 'ZodArray') {\n if ('_zod' in schema) {\n return [generateValidDataFromSchema(def.element, fieldName)];\n } else {\n return [generateValidDataFromSchema(def.type, fieldName)];\n }\n }\n\n if (typeName === 'ZodObject') {\n const shape = typeof def.shape === 'function' ? def.shape() : def.shape;\n const obj: any = {};\n for (const [key, fieldSchema] of Object.entries(shape)) {\n const fieldTypeName = getZodTypeName(fieldSchema as z.ZodTypeAny);\n if (fieldTypeName === 'ZodOptional') {\n // Special case: workflow routes need inputData field even when optional\n // because _run.start() expects { inputData?, ... } structure, not just {}\n // Without this, z.object({}).safeParse(undefined) fails with \"Required\" error\n if (key === 'inputData' || key === 'agent_id') {\n const fieldDef = getZodDef(fieldSchema as z.ZodTypeAny);\n const innerType = fieldDef.innerType;\n obj[key] = generateValidDataFromSchema(innerType, key);\n }\n continue;\n }\n obj[key] = generateValidDataFromSchema(fieldSchema as z.ZodTypeAny, key);\n }\n return obj;\n }\n\n if (typeName === 'ZodRecord') {\n return { key: generateValidDataFromSchema(def.valueType, fieldName) };\n }\n\n if (typeName === 'ZodUnion') {\n // Special case: for content field in messages, use string format (simpler and more reliable)\n if (fieldName === 'content') {\n // Check if one of the options is ZodString\n for (const option of def.options) {\n if (getZodTypeName(option) === 'ZodString') {\n return 'test message content';\n }\n }\n }\n return generateValidDataFromSchema(def.options[0], fieldName);\n }\n\n if (typeName === 'ZodDiscriminatedUnion') {\n const options = Array.from(def.options.values());\n return generateValidDataFromSchema(options[0] as z.ZodTypeAny, fieldName);\n }\n\n if (typeName === 'ZodIntersection') {\n const left = generateValidDataFromSchema(def.left, fieldName);\n const right = generateValidDataFromSchema(def.right, fieldName);\n return { ...left, ...right };\n }\n\n if (typeName === 'ZodTuple') {\n return def.items.map((item: z.ZodTypeAny) => generateValidDataFromSchema(item, fieldName));\n }\n\n if (typeName === 'ZodAny' || typeName === 'ZodUnknown') {\n if (fieldName === 'content') {\n return [{ type: 'text', text: 'test message content' }];\n }\n // Special case: message parts for processor messages\n if (fieldName === 'parts') {\n return [{ type: 'text', text: 'test message part' }];\n }\n // Special case: workflow inputData is z.unknown() but needs to be an object\n // to match the workflow's inputSchema (typically z.object({}))\n if (fieldName === 'inputData') {\n return {};\n }\n // Special case: memory messages are z.any() but handler validates they have threadId/resourceId\n // Note: This assumes we're generating a single message in an array context\n if (fieldName === 'messages') {\n return {\n role: 'user',\n content: [{ type: 'text', text: 'test message' }],\n threadId: 'test-thread',\n resourceId: 'test-resource',\n };\n }\n return 'test-value';\n }\n\n return undefined;\n}\n\nexport function getDefaultValidPathParams(route: ServerRoute): Record<string, any> {\n const params: Record<string, any> = {};\n\n // For stored agent routes (versions), use 'test-stored-agent' to match test context\n // For regular agent routes, use 'test-agent'\n if (route.path.includes(':agentId') && route.path.includes('/stored/agents/')) {\n params.agentId = 'test-stored-agent';\n } else if (route.path.includes(':agentId')) {\n params.agentId = 'test-agent';\n }\n if (route.path.includes(':workflowId')) params.workflowId = 'test-workflow';\n if (route.path.includes(':scheduleId')) params.scheduleId = 'test-schedule';\n if (route.path.includes(':backgroundTaskId')) params.backgroundTaskId = 'test-background-task-id';\n if (route.path.includes(':toolId')) params.toolId = 'test-tool';\n if (route.path.includes(':threadId')) params.threadId = 'test-thread';\n if (route.path.includes(':conversationId')) params.conversationId = 'test-thread';\n if (route.path.includes(':controllerId')) params.controllerId = 'test-controller';\n if (route.path.includes(':responseId')) params.responseId = 'test-response';\n if (route.path.includes(':resourceId')) params.resourceId = 'test-resource';\n if (route.path.includes(':sessionId')) params.sessionId = 'test-session';\n if (route.path.includes(':modelConfigId')) params.modelConfigId = 'id1';\n // For stored scorer version routes, use the stored scorer ID to match test context\n if (route.path.includes(':scorerId') && route.path.includes('/stored/scorers/')) {\n params.scorerId = 'test-stored-scorer';\n } else if (route.path.includes(':scorerId')) {\n params.scorerId = 'test-scorer';\n }\n if (route.path.includes(':scoreId')) params.scoreId = 'test-score';\n if (route.path.includes(':feedbackId')) params.feedbackId = 'test-feedback';\n if (route.path.includes(':traceId')) params.traceId = 'test-trace';\n if (route.path.includes(':runId')) params.runId = 'test-run';\n if (route.path.includes(':stepId')) params.stepId = 'test-step';\n if (route.path.includes(':taskId')) params.taskId = 'test-task-id';\n if (route.path.includes(':vectorName')) params.vectorName = 'test-vector';\n if (route.path.includes(':indexName')) params.indexName = 'test-index';\n if (route.path.includes(':transportId')) params.transportId = 'test-transport';\n if (route.path.includes(':spanId')) params.spanId = 'test-span';\n if (route.path.includes(':entityType')) params.entityType = 'AGENT';\n if (route.path.includes(':entityId')) params.entityId = 'test-agent';\n if (route.path.includes(':actionId')) params.actionId = 'merge-template';\n if (route.path.includes(':storedAgentId')) params.storedAgentId = 'test-stored-agent';\n if (route.path.includes(':storedScorerId')) params.storedScorerId = 'test-stored-scorer';\n if (route.path.includes(':roleId')) params.roleId = 'test-role';\n if (route.path.includes(':versionId')) params.versionId = 'test-version-id';\n if (route.path.includes(':processorId')) params.processorId = 'test-processor';\n // MCP route params - need to get actual server ID from test context\n if (route.path.includes(':id') && route.path.includes('/mcp/v0/servers/')) params.id = 'test-server-1';\n if (route.path.includes(':serverId')) params.serverId = 'test-server-1';\n if (route.path.includes(':toolId') && route.path.includes('/mcp/')) params.toolId = 'getWeather';\n\n // Workspace route params\n if (route.path.includes(':workspaceId')) params.workspaceId = 'test-workspace';\n\n // Skills route params\n if (route.path.includes(':skillName')) params.skillName = 'test-skill';\n if (route.path.includes(':referencePath')) params.referencePath = 'test-reference.md';\n\n // Stored entity route params\n if (route.path.includes(':storedMCPClientId')) params.storedMCPClientId = 'test-stored-mcp-client';\n if (route.path.includes(':mcpClientId')) params.mcpClientId = 'test-stored-mcp-client';\n if (route.path.includes(':storedPromptBlockId')) params.storedPromptBlockId = 'test-stored-prompt-block';\n if (route.path.includes(':promptBlockId')) params.promptBlockId = 'test-stored-prompt-block';\n if (route.path.includes(':storedWorkspaceId')) params.storedWorkspaceId = 'test-stored-workspace';\n if (route.path.includes(':storedSkillId')) params.storedSkillId = 'test-stored-skill';\n if (route.path.includes(':dynamicWorkflowId')) params.dynamicWorkflowId = 'test-dynamic-workflow';\n if (route.path.includes(':scorerId') && route.path.includes('/stored/scorers/'))\n params.scorerId = 'test-stored-scorer';\n\n // Dataset route params\n if (route.path.includes(':datasetId')) params.datasetId = 'test-dataset';\n if (route.path.includes(':itemId')) params.itemId = 'test-item';\n if (route.path.includes(':experimentId')) params.experimentId = 'test-experiment';\n if (route.path.includes(':resultId')) params.resultId = 'test-result';\n if (route.path.includes(':datasetVersion')) params.datasetVersion = '1';\n\n // Tool provider route params\n if (route.path.includes(':providerId')) params.providerId = 'test-provider';\n if (route.path.includes(':toolSlug')) params.toolSlug = 'test-tool-slug';\n if (route.path.includes(':authId')) params.authId = 'test-auth-id';\n if (route.path.includes(':connectionId')) params.connectionId = 'test-connection-id';\n\n // Channel route params\n if (route.path.includes(':platform')) params.platform = 'test-platform';\n\n // Builder registry route params\n if (route.path.includes(':registryId')) params.registryId = 'skills-sh';\n\n return params;\n}\n\nexport function getDefaultInvalidPathParams(route: ServerRoute): Array<Record<string, any>> {\n const invalid: Array<Record<string, any>> = [];\n invalid.push({});\n\n if (route.path.includes(':agentId')) {\n invalid.push({ agentId: 123 });\n }\n\n if (route.path.includes(':registryId')) {\n invalid.push({ registryId: 123 });\n }\n\n return invalid;\n}\n\n/**\n * Validate that a value matches a schema\n */\nexport function expectValidSchema(schema: ZodSchema, value: unknown) {\n const result = schema.safeParse(value);\n if (!result.success) {\n throw new Error(`Schema validation failed: ${JSON.stringify(result.error.issues, null, 2)}`);\n }\n}\n\n/**\n * Validate that a value does NOT match a schema\n */\nexport function expectInvalidSchema(schema: ZodSchema, value: unknown) {\n const result = schema.safeParse(value);\n if (result.success) {\n throw new Error(`Expected schema validation to fail, but it succeeded`);\n }\n}\n\n/**\n * Validate route metadata\n */\nexport function validateRouteMetadata(\n route: ServerRoute,\n expected: {\n method?: string;\n path?: string;\n responseType?: ServerRoute['responseType'];\n hasPathParams?: boolean;\n hasQueryParams?: boolean;\n hasBody?: boolean;\n hasResponse?: boolean;\n hasOpenAPI?: boolean;\n },\n) {\n if (expected.method && route.method !== expected.method) {\n throw new Error(`Expected method ${expected.method} but got ${route.method}`);\n }\n\n if (expected.path && route.path !== expected.path) {\n throw new Error(`Expected path ${expected.path} but got ${route.path}`);\n }\n\n if (expected.responseType && route.responseType !== expected.responseType) {\n throw new Error(`Expected responseType ${expected.responseType} but got ${route.responseType}`);\n }\n\n if (expected.hasPathParams !== undefined) {\n const hasPathParams = !!route.pathParamSchema;\n if (hasPathParams !== expected.hasPathParams) {\n throw new Error(\n `Expected pathParamSchema to be ${expected.hasPathParams ? 'defined' : 'undefined'} but got ${hasPathParams ? 'defined' : 'undefined'}`,\n );\n }\n }\n\n if (expected.hasQueryParams !== undefined) {\n const hasQueryParams = !!route.queryParamSchema;\n if (hasQueryParams !== expected.hasQueryParams) {\n throw new Error(\n `Expected queryParamSchema to be ${expected.hasQueryParams ? 'defined' : 'undefined'} but got ${hasQueryParams ? 'defined' : 'undefined'}`,\n );\n }\n }\n\n if (expected.hasBody !== undefined) {\n const hasBody = !!route.bodySchema;\n if (hasBody !== expected.hasBody) {\n throw new Error(\n `Expected bodySchema to be ${expected.hasBody ? 'defined' : 'undefined'} but got ${hasBody ? 'defined' : 'undefined'}`,\n );\n }\n }\n\n if (expected.hasResponse !== undefined) {\n const hasResponse = !!route.responseSchema;\n if (hasResponse !== expected.hasResponse) {\n throw new Error(\n `Expected responseSchema to be ${expected.hasResponse ? 'defined' : 'undefined'} but got ${hasResponse ? 'defined' : 'undefined'}`,\n );\n }\n }\n\n if (expected.hasOpenAPI !== undefined) {\n const hasOpenAPI = !!route.openapi;\n if (hasOpenAPI !== expected.hasOpenAPI) {\n throw new Error(\n `Expected openapi to be ${expected.hasOpenAPI ? 'defined' : 'undefined'} but got ${hasOpenAPI ? 'defined' : 'undefined'}`,\n );\n }\n }\n}\n","import type { ServerRoute } from '@mastra/server/server-adapter';\nimport { describe, it, expect } from 'vitest';\nimport {\n expectInvalidSchema,\n expectValidSchema,\n generateValidDataFromSchema,\n getDefaultValidPathParams,\n getDefaultInvalidPathParams,\n getRouteSpecificSchemaDefaults,\n validateRouteMetadata,\n} from './route-test-utils';\n\n/**\n * Configuration for route test suite\n */\nexport interface RouteTestConfig {\n /** Array of routes to test */\n routes: readonly ServerRoute[];\n}\n\n/**\n * Creates a standardized test suite for server adapter routes\n * Similar to stores/_test-utils pattern\n */\nexport function createRouteTestSuite(config: RouteTestConfig) {\n const { routes } = config;\n\n describe('Route Registration and Metadata', () => {\n it(`should have all ${routes.length} routes registered`, () => {\n expect(routes).toHaveLength(routes.length);\n });\n\n it('should have unique paths for each method', () => {\n const pathMethods = routes.map(r => `${r.method}:${r.path}`);\n const uniquePathMethods = new Set(pathMethods);\n expect(pathMethods.length).toBe(uniquePathMethods.size);\n });\n\n it('should have OpenAPI specs for all routes', () => {\n routes.forEach(route => {\n // Skip 'ALL' method routes - they can't have OpenAPI specs (no standard HTTP method mapping)\n // MCP transport routes use 'ALL' and are tested separately via mcp-transport-test-suite\n if (route.method === 'ALL') {\n return;\n }\n expect(route.openapi).toBeDefined();\n expect(route.openapi?.summary).toBeDefined();\n expect(route.openapi?.description).toBeDefined();\n });\n });\n });\n\n // Test each route\n routes.forEach(route => {\n const routeKey = `${route.method} ${route.path}`;\n\n describe(routeKey, () => {\n // Skip deprecated routes - they are placeholders for route parity only\n if (route.deprecated) {\n it('should be marked as deprecated', () => {\n expect(route.deprecated).toBe(true);\n expect(route.openapi?.deprecated).toBe(true);\n });\n return;\n }\n\n // Route configuration test\n it('should have correct route configuration', () => {\n expect(route).toBeDefined();\n validateRouteMetadata(route, {\n method: route.method,\n path: route.path,\n responseType: route.responseType,\n hasPathParams: !!route.pathParamSchema,\n hasQueryParams: !!route.queryParamSchema,\n hasBody: !!route.bodySchema,\n hasResponse: !!route.responseSchema,\n });\n });\n\n // Schema validation tests - always run\n // Path parameter validation\n if (route.pathParamSchema) {\n it('should validate path parameters', () => {\n const validParams = getDefaultValidPathParams(route);\n const invalidParams = getDefaultInvalidPathParams(route);\n\n expectValidSchema(route.pathParamSchema!, validParams);\n invalidParams.forEach((invalid: any) => {\n expectInvalidSchema(route.pathParamSchema!, invalid);\n });\n });\n }\n\n // Query parameter validation\n if (route.queryParamSchema) {\n it('should validate query parameters', () => {\n const routeDefaults = getRouteSpecificSchemaDefaults(route);\n const generated = generateValidDataFromSchema(route.queryParamSchema!);\n const validParams = { ...generated, ...(routeDefaults.query ?? {}) };\n expectValidSchema(route.queryParamSchema!, validParams);\n });\n }\n\n // Body validation\n if (route.bodySchema) {\n it('should validate request body schema', () => {\n const routeDefaults = getRouteSpecificSchemaDefaults(route);\n const generated = generateValidDataFromSchema(route.bodySchema!);\n const validBody = { ...generated, ...(routeDefaults.body ?? {}) };\n expectValidSchema(route.bodySchema!, validBody);\n });\n }\n\n // Response schema requirement for JSON endpoints\n if (route.responseType === 'json') {\n it('should have response schema defined for JSON endpoint', () => {\n if (!route.responseSchema) {\n throw new Error(\n `${route.method} ${route.path} is missing responseSchema. Add a Zod schema to ensure type safety and API documentation.`,\n );\n }\n });\n }\n });\n });\n}\n","import { randomUUID } from 'node:crypto';\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { Mastra } from '@mastra/core';\nimport { Agent, createMessageSignal, createSignal } from '@mastra/core/agent';\nimport { createScorer } from '@mastra/core/evals';\nimport { LogLevel } from '@mastra/core/logger';\nimport type { BaseLogMessage, IMastraLogger } from '@mastra/core/logger';\nimport { MockMemory } from '@mastra/core/memory';\nimport { SpanType } from '@mastra/core/observability';\nimport type { Processor, ProcessInputArgs, ProcessInputResult } from '@mastra/core/processors';\nimport { InMemoryStore } from '@mastra/core/storage';\nimport type { MemoryStorage } from '@mastra/core/storage';\nimport { UnknownToolProviderError } from '@mastra/core/tool-provider';\nimport { createTool } from '@mastra/core/tools';\nimport type { Tool } from '@mastra/core/tools';\nimport { getZodDef, getZodTypeName } from '@mastra/core/utils';\nimport { MastraVector } from '@mastra/core/vector';\nimport { CompositeVoice } from '@mastra/core/voice';\nimport type { Workflow } from '@mastra/core/workflows';\nimport { createWorkflow, createStep } from '@mastra/core/workflows';\nimport { Workspace, LocalFilesystem } from '@mastra/core/workspace';\nimport { MCPServer } from '@mastra/mcp';\nimport type { InMemoryTaskStore } from '@mastra/server/a2a/store';\nimport { WorkflowRegistry } from '@mastra/server/server-adapter';\nimport type { ServerRoute } from '@mastra/server/server-adapter';\nimport { expect, vi } from 'vitest';\nimport type { Mock } from 'vitest';\nimport * as zod from 'zod';\nimport type { ZodTypeAny } from 'zod';\nimport {\n generateValidDataFromSchema,\n getDefaultValidPathParams,\n getRouteSpecificSchemaDefaults,\n normalizeRoutePath,\n} from './route-test-utils';\nif (process.env.VITEST) {\n vi.mock('@mastra/core/vector');\n\n vi.mock('zod', async importOriginal => {\n const actual: {} = await importOriginal();\n return {\n ...actual,\n };\n });\n}\n\nconst z: any = zod;\n\n/**\n * Test context for adapter integration tests\n * Convention: Create entities with IDs that match auto-generated values:\n * - agentId: 'test-agent'\n * - workflowId: 'test-workflow'\n * - toolId: 'test-tool'\n * - etc.\n */\nexport interface AdapterTestContext {\n mastra: Mastra;\n tools?: Record<string, Tool>;\n taskStore?: InMemoryTaskStore;\n customRouteAuthConfig?: Map<string, boolean>;\n}\n\n/**\n * HTTP request to execute through adapter\n */\nexport interface HttpRequest {\n method: string;\n path: string;\n query?: Record<string, string | string[]>;\n body?: unknown;\n headers?: Record<string, string>;\n}\n\n/**\n * HTTP response from adapter\n */\nexport interface HttpResponse {\n status: number;\n type: 'json' | 'stream';\n data?: unknown;\n stream?: ReadableStream | AsyncIterable<unknown>;\n headers: Record<string, string>;\n}\n\n/**\n * Options for adapter setup\n */\nexport interface AdapterSetupOptions {\n /** Route prefix (e.g., '/v2' or '/api/v2') */\n prefix?: string;\n}\n\n/**\n * Configuration for adapter integration test suite\n */\nexport interface AdapterTestSuiteConfig {\n /** Name for the test suite */\n suiteName?: string;\n\n /** Values produced by the configured framework parser for an omitted body. */\n emptyBodyNormalization?: {\n withoutContentType: 'undefined' | 'empty-object' | 'empty-string';\n withJsonContentType: 'undefined' | 'empty-object' | 'empty-string';\n };\n\n /** Whether the adapter decodes requestContext from POST query parameters. */\n supportsPostQueryRequestContext?: boolean;\n\n /**\n * Setup adapter and app for testing\n * Called once before all tests\n * @param context - Test context with Mastra instance\n * @param options - Optional adapter options (e.g., prefix)\n */\n setupAdapter: (\n context: AdapterTestContext,\n options?: AdapterSetupOptions,\n ) => { adapter: any; app: any } | Promise<{ adapter: any; app: any }>;\n\n /**\n * Execute HTTP request through the adapter's framework (Express/Hono)\n */\n executeHttpRequest: (app: any, request: HttpRequest) => Promise<HttpResponse>;\n\n /**\n * Create test context with Mastra instance, agents, etc.\n * Convention: Create entities with IDs matching auto-generated values\n * Optional - uses createDefaultTestContext() if not provided\n */\n createTestContext?: () => Promise<AdapterTestContext> | AdapterTestContext;\n}\n\n/**\n * Creates a test agent with all common mocks configured\n */\nexport function createTestAgent(\n overrides: {\n id?: string;\n name?: string;\n description?: string;\n instructions?: string;\n tools?: Record<string, any>;\n voice?: CompositeVoice;\n memory?: MockMemory;\n model?: any;\n } = {},\n) {\n const testTool = createTestTool();\n const mockVoice = createMockVoice();\n const mockMemory = createMockMemory();\n\n const agent = new Agent({\n id: overrides.id || 'test-agent',\n name: overrides.name || 'test-agent',\n description: overrides.description || 'A test agent',\n instructions: overrides.instructions || 'Test instructions',\n model: overrides.model || 'openai/gpt-4o',\n tools: overrides.tools || { 'test-tool': testTool },\n voice: overrides.voice || mockVoice,\n memory: overrides.memory || mockMemory,\n });\n\n return agent;\n}\n\n/**\n * Creates a mock vector for testing (following handler test pattern)\n */\nexport function createMockVector() {\n // @ts-expect-error - Mocking for tests\n const mockVector: MastraVector = new MastraVector();\n mockVector.upsert = vi.fn().mockResolvedValue(['id1', 'id2']);\n mockVector.createIndex = vi.fn().mockResolvedValue(undefined);\n mockVector.query = vi.fn().mockResolvedValue([{ id: '1', score: 0.9, vector: [1, 2, 3] }]);\n mockVector.listIndexes = vi.fn().mockResolvedValue(['test-index']);\n mockVector.describeIndex = vi.fn().mockResolvedValue({ dimension: 3, count: 100, metric: 'cosine' });\n mockVector.deleteIndex = vi.fn().mockResolvedValue(undefined);\n\n return mockVector;\n}\n\nexport function mockAgentMethods(agent: Agent) {\n // Mock agent methods that would normally require API calls\n vi.spyOn(agent, 'generate').mockResolvedValue({ text: 'test response' } as any);\n\n // Create a reusable mock stream that returns a proper ReadableStream\n const createMockStream = () => {\n return new ReadableStream({\n start(controller) {\n controller.enqueue({ type: 'text-delta', textDelta: 'test' });\n controller.close();\n },\n });\n };\n\n // Mock stream method - returns object with fullStream property\n vi.spyOn(agent, 'stream').mockResolvedValue({ fullStream: createMockStream() } as any);\n\n // Mock resumeStream method - returns object with fullStream property\n vi.spyOn(agent, 'resumeStream').mockResolvedValue({ fullStream: createMockStream() } as any);\n\n // Mock legacy generate - returns GenerateTextResult (JSON object, not stream)\n vi.spyOn(agent, 'generateLegacy').mockResolvedValue({\n text: 'test response',\n toolCalls: [],\n finishReason: 'stop',\n usage: { promptTokens: 10, completionTokens: 5 },\n experimental_output: undefined,\n response: {\n id: 'test-response-id',\n timestamp: new Date(),\n modelId: 'gpt-4',\n },\n request: {},\n warnings: [],\n } as any);\n\n // Helper to create a mock Response object for datastream-response routes\n const createMockResponse = () => {\n const stream = createMockStream();\n return new Response(stream, {\n status: 200,\n headers: {\n 'Content-Type': 'text/plain; charset=utf-8',\n 'Transfer-Encoding': 'chunked',\n },\n });\n };\n\n // Mock streamLegacy - needs to return an object with toDataStreamResponse/toTextStreamResponse methods\n const mockStreamResult = {\n ...createMockStream(),\n toDataStreamResponse: vi.fn().mockImplementation(() => createMockResponse()),\n toTextStreamResponse: vi.fn().mockImplementation(() => createMockResponse()),\n };\n vi.spyOn(agent, 'streamLegacy').mockResolvedValue(mockStreamResult as any);\n\n // Mock approveToolCall method - returns object with fullStream property\n vi.spyOn(agent, 'approveToolCall').mockResolvedValue({ fullStream: createMockStream() } as any);\n\n // Mock declineToolCall method - returns object with fullStream property\n vi.spyOn(agent, 'declineToolCall').mockResolvedValue({ fullStream: createMockStream() } as any);\n\n // Mock approveToolCallGenerate method - returns same format as generate\n vi.spyOn(agent, 'approveToolCallGenerate').mockResolvedValue({ text: 'test response' } as any);\n\n // Mock declineToolCallGenerate method - returns same format as generate\n vi.spyOn(agent, 'declineToolCallGenerate').mockResolvedValue({ text: 'test response' } as any);\n\n vi.spyOn(agent, 'sendToolApproval').mockResolvedValue({\n accepted: true,\n runId: 'test-run',\n toolCallId: 'test-tool',\n } as any);\n\n // Mock network method\n vi.spyOn(agent, 'network').mockResolvedValue(createMockStream() as any);\n\n vi.spyOn(agent, 'sendSignal').mockImplementation((signal: any, target: any) => {\n const createdSignal = createSignal(signal);\n const runId = target?.runId ?? 'test-run';\n return {\n accepted: Promise.resolve({ action: 'deliver', runId }),\n signal: createdSignal,\n } as any;\n });\n\n vi.spyOn(agent, 'sendMessage').mockImplementation((message: any, target: any) => {\n const createdSignal = createMessageSignal(message);\n const runId = target?.runId ?? 'test-run';\n return {\n accepted: Promise.resolve({ action: 'deliver', runId }),\n signal: createdSignal,\n } as any;\n });\n\n vi.spyOn(agent, 'queueMessage').mockImplementation((message: any, target: any) => {\n const createdSignal = createMessageSignal(message);\n const runId = target?.runId ?? 'test-run';\n return {\n accepted: Promise.resolve({ action: 'deliver', runId }),\n signal: createdSignal,\n } as any;\n });\n\n vi.spyOn(agent, 'queueSignal').mockImplementation((signal: any, target: any) => {\n const createdSignal = createSignal(signal);\n const runId = target?.runId ?? 'test-run';\n return {\n accepted: Promise.resolve({ action: 'deliver', runId }),\n signal: createdSignal,\n } as any;\n });\n\n vi.spyOn(agent, 'subscribeToThread').mockResolvedValue({\n stream: (async function* () {\n yield { type: 'text-delta', textDelta: 'test' };\n })(),\n activeRunId: () => 'test-run',\n abort: vi.fn(() => true),\n unsubscribe: vi.fn(),\n } as any);\n\n // Mock getVoice to return the voice object that the handler expects\n const mockVoice = createMockVoice();\n\n // Mock voice methods to avoid \"No listener/speaker provider configured\" errors\n vi.spyOn(mockVoice, 'getSpeakers').mockResolvedValue([]);\n vi.spyOn(mockVoice, 'getListener').mockResolvedValue({ enabled: false } as any);\n vi.spyOn(mockVoice, 'speak').mockResolvedValue(\n new ReadableStream({\n start(controller) {\n controller.enqueue(new TextEncoder().encode('mock audio data'));\n controller.close();\n },\n }) as any,\n );\n vi.spyOn(mockVoice, 'listen').mockResolvedValue('transcribed text');\n\n vi.spyOn(agent, 'getVoice').mockResolvedValue(mockVoice);\n\n // Mock model list methods with proper model data structure\n vi.spyOn(agent, 'getModelList').mockResolvedValue([\n {\n id: 'id1',\n enabled: true,\n maxRetries: 3,\n modelId: 'gpt-4o',\n provider: 'openai',\n model: {\n modelId: 'gpt-4o',\n provider: 'openai',\n specificationVersion: 'v1',\n },\n },\n {\n id: 'id2',\n enabled: true,\n maxRetries: 3,\n modelId: 'gpt-4o-mini',\n provider: 'openai',\n model: {\n modelId: 'gpt-4o-mini',\n provider: 'openai',\n specificationVersion: 'v1',\n },\n },\n ] as any);\n\n return agent;\n}\n\n// Mock legacy workflow stream methods\nconst createMockWorkflowStream = () => {\n return new ReadableStream({\n start(controller) {\n controller.enqueue(new TextEncoder().encode('data: {\"type\":\"step-result\",\"result\":\"test\"}\\n\\n'));\n controller.close();\n },\n });\n};\n\n/**\n * Create a default test context with mocked Mastra instance, agents, workflows, etc.\n * This provides everything needed for adapter integration tests.\n */\nexport async function createDefaultTestContext(): Promise<AdapterTestContext> {\n // Mock OPENAI_API_KEY so that isProviderConnected('openai') returns true\n // This is needed for routes like ENHANCE_INSTRUCTIONS_ROUTE that check provider connectivity\n vi.stubEnv('OPENAI_API_KEY', 'test-api-key');\n\n // Create memory and pre-populate with test thread\n const memory = createMockMemory();\n await memory.createThread({\n threadId: 'test-thread',\n resourceId: 'test-resource',\n metadata: {},\n });\n\n // Create vector instance\n const vector = createMockVector();\n\n // Create test tool\n const testTool = createTestTool({ id: 'test-tool' });\n\n // Create test agent with memory and mocks\n const agent = createTestAgent({\n name: 'test-agent',\n memory,\n model: [\n { id: 'id1', model: 'openai/gpt-4o', maxRetries: 3 },\n { id: 'id2', model: 'openai/gpt-4o-mini', maxRetries: 3 },\n ],\n });\n mockAgentMethods(agent);\n\n // Mock Agent.prototype.generate for routes that create new Agent instances\n // (e.g., ENHANCE_INSTRUCTIONS_ROUTE creates a systemPromptAgent)\n // This needs to return both text and object for different use cases\n vi.spyOn(Agent.prototype, 'generate').mockResolvedValue({\n text: 'test response',\n object: {\n explanation: 'Enhanced the instructions for clarity and specificity.',\n new_prompt: 'You are a helpful assistant with enhanced instructions.',\n },\n } as any);\n\n // Create test workflow with mocks\n const workflow = createTestWorkflow({ id: 'test-workflow' });\n const mergeTemplateWorkflow = createTestWorkflow({ id: 'merge-template' });\n const workflowBuilderWorkflow = createTestWorkflow({ id: 'workflow-builder' });\n\n // Create test scorer\n const testScorer = createScorer({\n id: 'test-scorer',\n name: 'Test Scorer',\n description: 'Test scorer for observability tests',\n });\n\n // Create test processor\n const testProcessor = createTestProcessor({ id: 'test-processor' });\n\n mockLogger.transports = new Map([\n ['console', {}],\n ['file', {}],\n ]) as unknown as Record<string, unknown>;\n\n const mockLogs: BaseLogMessage[] = [createLog({})];\n\n mockLogger.listLogsByRunId.mockResolvedValue({\n logs: mockLogs,\n total: 1,\n page: 1,\n perPage: 100,\n hasMore: false,\n });\n\n mockLogger.listLogs.mockResolvedValue({ logs: mockLogs, total: 1, page: 1, perPage: 100, hasMore: false });\n\n const weatherTool = createTool({\n id: 'getWeather',\n description: 'Gets the current weather for a location',\n inputSchema: zod.z.object({\n location: zod.z.string().describe('The location to get weather for'),\n }),\n outputSchema: zod.z.object({\n temperature: zod.z.number(),\n condition: zod.z.string(),\n }),\n execute: async ({ location }) => ({\n temperature: 72,\n condition: `Sunny in ${location}`,\n }),\n });\n\n const calculatorTool = createTool({\n id: 'calculate',\n description: 'Performs basic calculations',\n inputSchema: zod.z.object({\n operation: zod.z.enum(['add', 'subtract', 'multiply', 'divide']),\n a: zod.z.number(),\n b: zod.z.number(),\n }),\n outputSchema: zod.z.object({\n result: zod.z.number(),\n }),\n execute: async ({ operation, a, b }) => {\n let result = 0;\n switch (operation) {\n case 'add':\n result = a + b;\n break;\n case 'subtract':\n result = a - b;\n break;\n case 'multiply':\n result = a * b;\n break;\n case 'divide':\n result = b !== 0 ? a / b : Infinity;\n break;\n }\n return { result };\n },\n });\n\n const failingTool = createTool({\n id: 'failingTool',\n description: 'A tool that always throws an error for testing error handling',\n inputSchema: z.object({}),\n outputSchema: z.object({}),\n execute: async () => {\n throw new Error('Tool execution failed intentionally');\n },\n });\n\n // Create real MCP servers with tools and app resources\n const mcpServer1 = new MCPServer({\n name: 'Test Server 1',\n version: '1.0.0',\n description: 'Test MCP Server 1',\n tools: {\n getWeather: weatherTool,\n calculate: calculatorTool,\n },\n appResources: {\n 'ui://test/app': {\n name: 'Test App',\n html: '<html><body>Test</body></html>',\n },\n },\n });\n\n const mcpServer2 = new MCPServer({\n name: 'Test Server 2',\n version: '1.1.0',\n description: 'Test MCP Server 2',\n tools: {\n failingTool: failingTool,\n },\n appResources: {\n 'ui://test/app2': {\n name: 'Test App 2',\n html: '<html><body>Test 2</body></html>',\n },\n },\n });\n\n // Create test workspace with local filesystem and mock files\n const workspace = await createTestWorkspace();\n\n // Create Mastra instance with all test entities\n // Mock channel provider for channel route tests\n const mockChannelProvider = {\n id: 'test-platform',\n getRoutes: () => [],\n getInfo: () => ({\n id: 'test-platform',\n name: 'Test Platform',\n isConfigured: true,\n }),\n connect: async () => ({\n type: 'immediate' as const,\n installationId: 'test-installation',\n }),\n disconnect: async () => {},\n listInstallations: async () => [\n {\n id: 'test-installation',\n platform: 'test-platform',\n agentId: 'test-agent',\n status: 'active' as const,\n displayName: 'Test Installation',\n installedAt: new Date(),\n },\n ],\n };\n\n const mastra = new Mastra({\n logger: mockLogger as unknown as IMastraLogger,\n storage: new InMemoryStore(),\n agents: {\n 'test-agent': agent,\n },\n workflows: {\n 'test-workflow': workflow,\n },\n scorers: { 'test-scorer': testScorer },\n vectors: { 'test-vector': vector },\n mcpServers: {\n 'test-server-1': mcpServer1,\n 'test-server-2': mcpServer2,\n },\n workspace,\n processors: {\n 'test-processor': testProcessor,\n },\n backgroundTasks: {\n enabled: true,\n },\n channels: {\n 'test-platform': mockChannelProvider as any,\n },\n });\n\n // Mock getEditor to return an object with namespaced methods for stored agents routes\n const mockToolProvider = {\n info: { id: 'test-provider', name: 'Test Provider', description: 'A test tool provider' },\n listToolkits: vi.fn().mockResolvedValue({ data: [] }),\n listTools: vi.fn().mockResolvedValue({ data: [], total: 0, page: 0, perPage: 20, hasMore: false }),\n getToolSchema: vi.fn().mockResolvedValue({ name: 'test-tool-slug', inputSchema: {}, outputSchema: {} }),\n };\n const mockProcessorProvider = {\n info: { id: 'test-provider', name: 'Test Processor Provider', description: 'A test processor provider' },\n configSchema: z.object({}),\n availablePhases: ['processInput'] as const,\n createProcessor: vi.fn(),\n };\n vi.spyOn(mastra, 'getEditor').mockReturnValue({\n hasEnabledBuilderConfig: () => true,\n resolveBuilder: async () => ({\n enabled: true,\n getFeatures: () => ({ agent: { favorites: true } }),\n getConfiguration: () => undefined,\n getModelPolicyWarnings: () => [],\n }),\n hasEnabledWorkflowBuilderConfig: () => true,\n resolveWorkflowBuilder: async () => ({\n enabled: true,\n getAgent: () => agent,\n getModelPolicy: () => undefined,\n }),\n prompt: {\n preview: vi.fn().mockResolvedValue('resolved instructions preview'),\n clearCache: vi.fn(),\n },\n mcp: {\n clearCache: vi.fn(),\n },\n agent: {\n list: vi.fn().mockResolvedValue({ agents: [] }),\n clearCache: vi.fn(),\n create: vi.fn().mockImplementation(async (input: any) => {\n // Delegate to storage directly, mirroring what editor.agent.create does\n const agents = await mastra.getStorage()!.getStore('agents');\n return agents!.create({ agent: input });\n }),\n clone: vi.fn().mockResolvedValue({\n id: 'cloned-agent',\n name: 'Test Agent (Clone)',\n status: 'draft',\n description: '',\n instructions: 'test instructions',\n model: { provider: 'openai', name: 'gpt-4o' },\n createdAt: new Date(),\n updatedAt: new Date(),\n }),\n },\n scorer: {\n clearCache: vi.fn(),\n },\n getToolProviders: vi.fn().mockReturnValue({ 'test-provider': mockToolProvider }),\n getToolProvider: vi\n .fn()\n .mockImplementation((id: string) => (id === 'test-provider' ? mockToolProvider : undefined)),\n getToolProviderOrThrow: vi.fn().mockImplementation((id: string) => {\n if (id === 'test-provider') return mockToolProvider;\n throw new UnknownToolProviderError(id, ['test-provider']);\n }),\n getProcessorProviders: vi.fn().mockReturnValue({ 'test-provider': mockProcessorProvider }),\n getProcessorProvider: vi\n .fn()\n .mockImplementation((id: string) => (id === 'test-provider' ? mockProcessorProvider : undefined)),\n } as any);\n\n await mockWorkflowRun(workflow);\n await setupWorkflowRegistryMocks(\n {\n 'merge-template': mergeTemplateWorkflow,\n 'workflow-builder': workflowBuilderWorkflow,\n },\n mastra,\n );\n\n // Add test trace by creating a span with that traceId\n const storage = mastra.getStorage();\n if (storage) {\n const observability = await storage.getStore('observability');\n if (observability) {\n vi.spyOn(observability, 'getFeatures').mockReturnValue([\n ...(observability.getFeatures() ?? []),\n 'trace-query',\n 'trace-query-discovery',\n 'trace-aggregate',\n 'thread-query',\n 'thread-query-rows',\n 'span-query',\n ]);\n vi.spyOn(observability, 'queryTraces').mockResolvedValue({ traces: [], page: { next: null } });\n vi.spyOn(observability, 'aggregateTraces').mockResolvedValue({ rows: [], truncated: false });\n vi.spyOn(observability, 'getTraceQueryObservedFields').mockResolvedValue({\n observedFields: [],\n observedFieldsTruncated: false,\n });\n vi.spyOn(observability, 'getTraceQueryValues').mockResolvedValue({ values: [], valuesTruncated: false });\n vi.spyOn(observability, 'queryThreads').mockResolvedValue({ threads: [], page: { next: null } });\n vi.spyOn(observability, 'querySpans').mockResolvedValue({ spans: [], page: { next: null } });\n await observability.createSpan({\n span: {\n spanId: 'test-span',\n traceId: 'test-trace',\n name: 'test-span',\n spanType: SpanType.GENERIC,\n startedAt: new Date(),\n endedAt: new Date(),\n isEvent: false,\n },\n });\n\n // Add test feedback for the review-status route\n await observability.createFeedback({\n feedback: {\n feedbackId: 'test-feedback',\n timestamp: new Date(),\n traceId: 'test-trace',\n spanId: 'test-span',\n feedbackSource: 'user',\n feedbackType: 'comment',\n value: 'test feedback',\n reviewStatus: 'needs-review',\n },\n });\n }\n\n // Add test stored agent for stored agents routes\n const agents = await storage.getStore('agents');\n if (agents) {\n // create automatically creates version 1 with the initial config\n const storedAgent = await agents.create({\n agent: {\n id: 'test-stored-agent',\n name: 'Test Stored Agent',\n description: 'A test stored agent for integration tests',\n instructions: 'Test instructions for stored agent',\n model: { provider: 'openai', name: 'gpt-4o' },\n },\n });\n\n // Version 1 was auto-created by create; its ID is the activeVersionId\n const version1Id = storedAgent.activeVersionId!;\n\n // Version 2: Non-active version that can be deleted or used in comparisons\n // Config fields are top-level (no snapshot object)\n await agents.createVersion({\n id: 'test-version-id',\n agentId: 'test-stored-agent',\n versionNumber: 2,\n name: 'Test Stored Agent',\n instructions: 'Updated test instructions for version 2',\n model: { provider: 'openai', name: 'gpt-4o' },\n changedFields: ['instructions'],\n changeMessage: 'Second test version',\n });\n\n // Ensure version 1 stays active, leaving version 2 (test-version-id) as non-active and deletable\n await agents.update({\n id: 'test-stored-agent',\n activeVersionId: version1Id,\n });\n }\n\n // Add test stored scorer for stored scorers routes\n const scorers = await storage.getStore('scorerDefinitions');\n if (scorers) {\n const storedScorer = await scorers.create({\n scorerDefinition: {\n id: 'test-stored-scorer',\n name: 'Test Stored Scorer',\n description: 'A test stored scorer for integration tests',\n type: 'llm-judge',\n instructions: 'Evaluate the response for accuracy.',\n model: { provider: 'openai', name: 'gpt-4o' },\n scoreRange: { min: 0, max: 1 },\n },\n });\n // Version 2 with known ID for version-specific route tests\n await scorers.createVersion({\n id: 'test-version-id',\n scorerDefinitionId: 'test-stored-scorer',\n versionNumber: 2,\n name: 'Test Stored Scorer',\n type: 'llm-judge',\n instructions: 'Updated instructions for version 2.',\n model: { provider: 'openai', name: 'gpt-4o' },\n scoreRange: { min: 0, max: 1 },\n changedFields: ['instructions'],\n changeMessage: 'Second test version',\n });\n }\n\n // Add test stored MCP client with version 2 (version 1 is auto-created by create())\n const mcpClients = await storage.getStore('mcpClients');\n if (mcpClients) {\n await mcpClients.create({\n mcpClient: {\n id: 'test-stored-mcp-client',\n name: 'Test Stored MCP Client',\n servers: { 'test-server': { type: 'http', url: 'http://localhost:3000' } },\n },\n });\n await mcpClients.createVersion({\n id: 'test-version-id',\n mcpClientId: 'test-stored-mcp-client',\n versionNumber: 2,\n name: 'Test Stored MCP Client',\n servers: { 'test-server': { type: 'http', url: 'http://localhost:3001' } },\n changedFields: ['servers'],\n changeMessage: 'Second test version',\n });\n }\n\n // Add test stored prompt block with version 2\n const promptBlocks = await storage.getStore('promptBlocks');\n if (promptBlocks) {\n await promptBlocks.create({\n promptBlock: {\n id: 'test-stored-prompt-block',\n name: 'Test Stored Prompt Block',\n content: 'Hello {{name}}, this is a test prompt block.',\n },\n });\n await promptBlocks.createVersion({\n id: 'test-version-id',\n blockId: 'test-stored-prompt-block',\n versionNumber: 2,\n name: 'Test Stored Prompt Block',\n content: 'Updated content for {{name}}.',\n changedFields: ['content'],\n changeMessage: 'Second test version',\n });\n }\n\n // Add test stored workspace and skill (no extra versions needed)\n const workspaces = await storage.getStore('workspaces');\n if (workspaces) {\n await workspaces.create({\n workspace: { id: 'test-stored-workspace', name: 'Test Stored Workspace' },\n });\n }\n const skills = await storage.getStore('skills');\n if (skills) {\n await skills.create({\n skill: {\n id: 'test-stored-skill',\n name: 'test-stored-skill',\n description: 'A test stored skill',\n instructions: 'Test skill instructions',\n },\n });\n }\n\n // Add test dynamic workflow definition so GET /stored/workflows/:dynamicWorkflowId\n // finds a row matching getDefaultValidPathParams' 'test-dynamic-workflow'\n const workflowDefinitions = await storage.getStore('workflowDefinitions');\n if (workflowDefinitions) {\n await workflowDefinitions.upsert({\n id: 'test-dynamic-workflow',\n description: 'Test dynamic workflow',\n inputSchema: { type: 'object', properties: { name: { type: 'string' } }, required: ['name'] },\n outputSchema: { type: 'object', properties: { message: { type: 'string' } } },\n graph: [\n {\n type: 'mapping',\n id: 'greet',\n mapConfig: JSON.stringify({ message: { template: 'Hello, ${initData.name}!' } }),\n },\n ],\n });\n }\n\n const backgroundTasks = await storage.getStore('backgroundTasks');\n if (backgroundTasks) {\n await backgroundTasks.createTask({\n id: 'test-background-task-id',\n status: 'pending',\n toolName: 'test-tool',\n toolCallId: 'test-tool-call-id',\n agentId: 'test-agent',\n runId: 'test-run',\n args: { query: 'test' },\n retryCount: 0,\n maxRetries: 0,\n timeoutMs: 300_000,\n createdAt: new Date(),\n });\n\n await backgroundTasks.updateTask('test-background-task-id', {\n status: 'running',\n startedAt: new Date(),\n });\n }\n\n const schedules = await storage.getStore('schedules');\n if (schedules) {\n const now = Date.now();\n await schedules.createSchedule({\n id: 'test-schedule',\n target: { type: 'workflow', workflowId: 'test-workflow' },\n cron: '* * * * *',\n status: 'active',\n nextFireAt: now + 60_000,\n createdAt: now,\n updatedAt: now,\n });\n await schedules.createSchedule({\n id: 'agent_test-agent-schedule',\n target: { type: 'agent', agentId: 'test-agent', prompt: 'ping' },\n cron: '* * * * *',\n status: 'active',\n nextFireAt: now + 60_000,\n createdAt: now,\n updatedAt: now,\n });\n }\n\n const saveStoredResponseFixtures = async (memoryStore: MemoryStorage | undefined) => {\n if (!memoryStore) {\n return;\n }\n\n await memoryStore.saveThread({\n thread: {\n id: 'test-thread',\n resourceId: 'test-resource',\n createdAt: new Date(),\n updatedAt: new Date(),\n metadata: {},\n },\n });\n await memoryStore.saveMessages({\n messages: [\n {\n id: 'test-message-1',\n threadId: 'test-thread',\n role: 'user',\n content: {\n format: 2,\n parts: [{ type: 'text', text: 'Test message' }],\n },\n createdAt: new Date(),\n },\n {\n id: 'test-response',\n threadId: 'test-thread',\n resourceId: 'test-resource',\n role: 'assistant',\n type: 'text',\n content: {\n format: 2,\n parts: [{ type: 'text', text: 'Test stored response' }],\n metadata: {\n mastra: {\n response: {\n agentId: 'test-agent',\n model: 'openai/gpt-4o',\n createdAt: Math.floor(Date.now() / 1000),\n completedAt: Math.floor(Date.now() / 1000),\n status: 'completed',\n usage: null,\n tools: [],\n store: true,\n messageIds: ['test-message-1', 'test-response'],\n },\n },\n },\n },\n createdAt: new Date(),\n },\n ],\n });\n };\n\n // Seed the root memory store for routes that resolve memory directly from Mastra storage.\n await saveStoredResponseFixtures(await storage.getStore('memory'));\n\n // Seed the agent memory store for Responses routes that now resolve stored responses\n // through agent memory first and only inherit root storage via the agent-memory path.\n await saveStoredResponseFixtures(await memory.storage.getStore('memory'));\n }\n\n return {\n mastra,\n tools: { 'test-tool': testTool },\n };\n}\n\nasync function mockWorkflowRun(workflow: Workflow<any, any, any, any, any, any, any, any>) {\n // Mock getWorkflowRunById to return a mock WorkflowState object\n // This is the unified format that includes both metadata and processed execution state\n // Only 'test-run' exists; unknown runIds resolve to null so stream routes can\n // start fresh runs without tripping the terminal-run 409 guard.\n vi.spyOn(workflow, 'getWorkflowRunById').mockImplementation(async (runId: string) =>\n runId !== 'test-run'\n ? (null as any)\n : ({\n runId: 'test-run',\n workflowName: 'test-workflow',\n resourceId: 'test-resource',\n createdAt: new Date(),\n updatedAt: new Date(),\n status: 'success',\n result: { output: 'test-output' },\n payload: {},\n steps: {\n step1: {\n status: 'success',\n output: { result: 'test-output' },\n startedAt: Date.now() - 1000,\n endedAt: Date.now(),\n },\n },\n activeStepsPath: {},\n serializedStepGraph: [{ type: 'step', step: { id: 'step1' } }],\n } as any),\n );\n\n // Mock createRun to return a mocked run object with all required methods\n const originalCreateRun = workflow.createRun.bind(workflow);\n vi.spyOn(workflow, 'createRun').mockImplementation(async (options?: any) => {\n const run = await originalCreateRun(options);\n\n // Mock stream methods\n vi.spyOn(run, 'streamLegacy').mockReturnValue({\n stream: createMockWorkflowStream(),\n } as any);\n vi.spyOn(run, 'observeStreamLegacy').mockReturnValue({\n stream: createMockWorkflowStream(),\n } as any);\n\n // Mock start to return a successful result\n vi.spyOn(run, 'start').mockResolvedValue({\n results: {},\n status: 'success',\n } as any);\n\n // Mock restart to return a successful result\n vi.spyOn(run, 'restart').mockResolvedValue({\n results: {},\n status: 'success',\n } as any);\n\n // Mock resume to return a successful result\n vi.spyOn(run, 'resume').mockResolvedValue({\n results: {},\n status: 'success',\n } as any);\n\n // Mock timeTravel to return a successful result\n vi.spyOn(run, 'timeTravel').mockResolvedValue({\n results: {},\n status: 'success',\n } as any);\n\n return run;\n });\n}\n\n/**\n * Creates a mock voice provider\n */\nexport function createMockVoice() {\n return new CompositeVoice({});\n}\n\n/**\n * Creates a test workspace with a local filesystem and mock skill files.\n * Uses a temporary directory that gets cleaned up after tests.\n */\nexport async function createTestWorkspace(): Promise<Workspace> {\n // Create a temp directory for the test workspace\n const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mastra-test-workspace-'));\n\n // Create skills directory and a test skill\n const skillsDir = path.join(tempDir, 'skills', 'test-skill');\n fs.mkdirSync(skillsDir, { recursive: true });\n\n // Create SKILL.md file for the test skill\n const skillContent = `---\nname: test-skill\ndescription: A test skill for integration testing\nlicense: MIT\ncompatibility: \">=1.0.0\"\n---\n\n# Test Skill\n\nThis is a test skill used for integration testing.\n\n## Instructions\n\nFollow these instructions for the test skill.\n`;\n fs.writeFileSync(path.join(skillsDir, 'SKILL.md'), skillContent);\n\n // Create a test reference file in the references subdirectory\n const referencesDir = path.join(skillsDir, 'references');\n fs.mkdirSync(referencesDir, { recursive: true });\n fs.writeFileSync(path.join(referencesDir, 'test-reference.md'), '# Test Reference\\n\\nThis is a test reference file.');\n\n // Create a regular test file in the workspace root\n fs.writeFileSync(path.join(tempDir, 'test-file.txt'), 'Hello from test workspace!');\n\n // Create a test directory for list operations\n const testDir = path.join(tempDir, 'test-dir');\n fs.mkdirSync(testDir, { recursive: true });\n fs.writeFileSync(path.join(testDir, 'nested-file.txt'), 'Nested file content');\n\n // Create .agents/skills/ structure for skills-sh routes (remove, check-updates, update)\n const agentSkillsDir = path.join(tempDir, '.agents', 'skills', 'test-skill');\n fs.mkdirSync(agentSkillsDir, { recursive: true });\n fs.writeFileSync(path.join(agentSkillsDir, 'SKILL.md'), skillContent);\n\n // Create .meta.json for the installed skill (used by update routes)\n // Use a fixed timestamp for deterministic tests\n const installedAt = new Date('2024-01-01T00:00:00.000Z').toISOString();\n const metaJson = {\n skillName: 'test-skill',\n owner: 'test-owner',\n repo: 'test-repo',\n branch: 'main',\n installedAt,\n };\n fs.writeFileSync(path.join(agentSkillsDir, '.meta.json'), JSON.stringify(metaJson, null, 2));\n\n // Create the workspace with local filesystem and BM25 search\n // Use 'test-workspace' as the ID to match test utilities' getDefaultValidPathParams\n const filesystem = new LocalFilesystem({ basePath: tempDir });\n const workspace = new Workspace({\n id: 'test-workspace',\n filesystem,\n skills: ['skills'],\n bm25: true, // Enable BM25 search for index/unindex operations\n });\n\n // Initialize the workspace\n await workspace.init();\n\n return workspace;\n}\n\n/**\n * Creates a test tool with basic schema\n */\nexport function createTestTool(\n overrides: {\n id?: string;\n description?: string;\n inputSchema?: ZodTypeAny;\n outputSchema?: ZodTypeAny;\n execute?: (input: any) => Promise<any>;\n } = {},\n) {\n return createTool({\n id: overrides.id || 'test-tool',\n description: overrides.description || 'A test tool',\n inputSchema: overrides.inputSchema || z.object({ key: z.string() }),\n outputSchema: overrides.outputSchema || z.object({ result: z.string() }),\n execute: overrides.execute || (async _inputData => ({ result: 'success' })),\n });\n}\n\n/**\n * Creates a mock memory instance with InMemoryStore\n * Following the pattern from handler tests - uses actual MockMemory implementation\n */\nexport function createMockMemory() {\n const storage = new InMemoryStore();\n const mockMemory = new MockMemory({ storage });\n (mockMemory as any).__registerMastra = vi.fn();\n return mockMemory;\n}\n\n/**\n * Creates a test processor for integration tests\n */\nexport function createTestProcessor(\n overrides: {\n id?: string;\n name?: string;\n description?: string;\n } = {},\n): Processor {\n return {\n id: overrides.id || 'test-processor',\n name: overrides.name || 'Test Processor',\n description: overrides.description || 'A test processor for integration tests',\n async processInput({ messages }: ProcessInputArgs): Promise<ProcessInputResult> {\n // Simple pass-through processor\n return messages;\n },\n };\n}\n\n/**\n * Creates a test workflow with a suspending step\n * Following the pattern from handler tests - always includes suspend for resume tests\n */\nexport function createTestWorkflow(\n overrides: {\n id?: string;\n description?: string;\n } = {},\n) {\n const execute = vi.fn(async (_args: unknown) => ({ result: 'success' }));\n const stepA = createStep({\n id: 'test-step',\n inputSchema: z.object({}),\n outputSchema: z.object({}),\n execute: async ({ suspend }: any) => {\n await suspend({ test: 'data' });\n },\n });\n const stepB = createStep({\n id: 'test-step2',\n inputSchema: z.object({ name: z.string() }),\n outputSchema: z.object({ result: z.string() }),\n execute: async args => execute(args),\n });\n\n return createWorkflow({\n id: overrides.id || 'test-workflow',\n description: overrides.description || 'A test workflow',\n steps: [stepA, stepB],\n inputSchema: z.object({}),\n outputSchema: z.object({ result: z.string() }),\n })\n .then(stepA)\n .then(stepB)\n .commit();\n}\n\n/**\n * Recursively converts ISO date strings to Date objects in response data.\n * This is needed because HTTP responses serialize dates to strings via JSON.stringify(),\n * but schemas expect Date objects for validation.\n *\n * @param data - The response data from HTTP (with dates as ISO strings)\n * @returns The same data with ISO date strings converted to Date objects\n */\n/**\n * Check if a Zod schema expects a Date type at a given path\n */\nfunction schemaExpectsDate(schema: any, path: string[] = []): boolean {\n if (!schema) return false;\n\n let typeName = getZodTypeName(schema);\n let def = getZodDef(schema);\n\n // Unwrap effects, optional, nullable, default to get to the base type\n while (\n typeName === 'ZodEffects' ||\n typeName === 'ZodOptional' ||\n typeName === 'ZodNullable' ||\n typeName === 'ZodDefault'\n ) {\n if (typeName === 'ZodEffects') {\n schema = schema._def.schema;\n } else if (typeName === 'ZodOptional' || typeName === 'ZodNullable') {\n schema = def.innerType;\n } else if (typeName === 'ZodDefault') {\n schema = def.innerType;\n }\n typeName = getZodTypeName(schema);\n def = getZodDef(schema);\n }\n\n typeName = getZodTypeName(schema);\n def = getZodDef(schema);\n\n // If we have a path, navigate to that field\n if (path.length > 0) {\n const [fieldName] = path;\n if (!fieldName) {\n return false;\n }\n if (typeName === 'ZodObject') {\n const shape = typeof def.shape === 'function' ? def.shape() : def.shape;\n const fieldSchema = shape[fieldName];\n return schemaExpectsDate(fieldSchema, path.slice(1));\n } else if (typeName === 'ZodArray') {\n // For arrays, check the element type (ignore the array index in path)\n return schemaExpectsDate(def.element, path.slice(1));\n }\n return false;\n }\n\n // Check if this is a Date type\n return typeName === 'ZodDate';\n}\n\nexport function parseDatesInResponse(data: any, schema?: any, currentPath: string[] = []): any {\n if (data === null || data === undefined) {\n return data;\n }\n\n if (typeof data === 'string') {\n // Only parse dates if the schema expects a Date at this path\n if (schema && schemaExpectsDate(schema, currentPath)) {\n const isoDateRegex = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z?$/;\n if (isoDateRegex.test(data)) {\n const parsed = new Date(data);\n if (!isNaN(parsed.getTime())) {\n return parsed;\n }\n }\n }\n return data;\n }\n\n if (Array.isArray(data)) {\n return data.map((item, index) => parseDatesInResponse(item, schema, [...currentPath, String(index)]));\n }\n\n if (typeof data === 'object') {\n const result: any = {};\n for (const [key, value] of Object.entries(data)) {\n result[key] = parseDatesInResponse(value, schema, [...currentPath, key]);\n }\n return result;\n }\n\n return data;\n}\n\nasync function setupWorkflowRegistryMocks(\n workflows: Record<string, Workflow<any, any, any, any, any, any, any, any>>,\n mastra: Mastra,\n) {\n for (const workflow of Object.values(workflows)) {\n workflow.__registerMastra(mastra);\n workflow.__registerPrimitives({\n logger: mastra.getLogger(),\n storage: mastra.getStorage(),\n agents: mastra.listAgents(),\n tts: mastra.getTTS(),\n vectors: mastra.listVectors(),\n });\n await mockWorkflowRun(workflow);\n }\n\n // Mock WorkflowRegistry.registerTemporaryWorkflows to attach Mastra to workflows\n vi.spyOn(WorkflowRegistry, 'registerTemporaryWorkflows').mockImplementation(() => {\n for (const [id, workflow] of Object.entries(workflows)) {\n // Register Mastra instance with the workflow\n if (mastra) {\n workflow.__registerMastra(mastra);\n workflow.__registerPrimitives({\n logger: mastra.getLogger(),\n storage: mastra.getStorage(),\n agents: mastra.listAgents(),\n tts: mastra.getTTS(),\n vectors: mastra.listVectors(),\n });\n }\n WorkflowRegistry['additionalWorkflows'][id] = workflow;\n }\n });\n}\n\nexport function createLog(args: Partial<BaseLogMessage>): BaseLogMessage {\n return {\n msg: 'test log',\n level: LogLevel.INFO,\n time: new Date(),\n ...args,\n pid: 1,\n hostname: 'test-host',\n name: 'test-name',\n runId: 'test-run',\n };\n}\n\ntype MockedLogger = {\n listLogsByRunId: Mock<IMastraLogger['listLogsByRunId']>;\n listLogs: Mock<IMastraLogger['listLogs']>;\n};\n\nconst mockLogger = {\n listLogsByRunId: vi.fn(),\n listLogs: vi.fn(),\n transports: new Map<string, unknown>(),\n warn: vi.fn(),\n info: vi.fn(),\n debug: vi.fn(),\n error: vi.fn(),\n cleanup: vi.fn(),\n trackException: vi.fn(),\n getTransports: vi.fn(() => mockLogger.transports ?? new Map<string, unknown>()),\n} as unknown as MockedLogger & {\n transports: Record<string, unknown>;\n getTransports: () => Map<string, unknown>;\n};\n\nexport interface RouteRequestPayload {\n method: ServerRoute['method'];\n path: string;\n query?: Record<string, string | string[]>;\n body?: unknown;\n}\n\nexport interface RouteRequestOverrides {\n pathParams?: Record<string, string>;\n query?: Record<string, unknown>;\n body?: Record<string, unknown>;\n /** Route prefix to prepend to the route path (defaults to '/api') */\n prefix?: string;\n}\n\n/**\n * Get route-specific defaults for path fields based on the route.\n * Different routes need different kinds of paths (files vs directories).\n */\nfunction getRouteSpecificPathDefaults(route: ServerRoute): {\n query?: Record<string, unknown>;\n body?: Record<string, unknown>;\n} {\n const routePath = route.path;\n\n // File operations need file paths\n if (\n routePath.includes('/fs/read') ||\n routePath.includes('/fs/write') ||\n routePath.includes('/fs/delete') ||\n routePath.includes('/fs/stat')\n ) {\n return { query: { path: 'test-file.txt' }, body: { path: 'test-file.txt' } };\n }\n\n // Directory operations need directory paths\n if (routePath.includes('/fs/list')) {\n return { query: { path: '.' } };\n }\n\n // mkdir needs a new path to create\n if (routePath.includes('/fs/mkdir')) {\n return { body: { path: 'new-test-dir' } };\n }\n\n // Index/unindex operations\n if (routePath.includes('/workspace/index') || routePath.includes('/workspace/unindex')) {\n return { query: { path: 'test-file.txt' }, body: { path: 'test-file.txt' } };\n }\n\n // Workflow stream routes reject runIds whose run already finished (409),\n // so each request needs a fresh runId instead of the shared 'test-run'.\n if (routePath === '/workflows/:workflowId/stream' || routePath === '/agent-builder/:actionId/stream') {\n return { query: { runId: `test-run-${randomUUID()}` } };\n }\n\n // MCP tool execution validates `data` against the tool's input schema and\n // answers 400 when it does not match; the default path targets getWeather.\n if (routePath === '/mcp/:serverId/tools/:toolId/execute') {\n return { body: { data: { location: 'test-location' } } };\n }\n\n return {};\n}\n\nexport function buildRouteRequest(route: ServerRoute, overrides: RouteRequestOverrides = {}): RouteRequestPayload {\n const method = route.method;\n const prefix = normalizeRoutePath(overrides.prefix ?? '/api');\n let path = `${prefix}${route.path}`;\n\n if (route.pathParamSchema) {\n const defaults = getDefaultValidPathParams(route);\n const params = { ...defaults, ...(overrides.pathParams ?? {}) };\n for (const [key, value] of Object.entries(params)) {\n path = path.replace(`:${key}`, encodeURIComponent(String(value)));\n }\n }\n\n const pathDefaults = getRouteSpecificPathDefaults(route);\n const schemaDefaults = getRouteSpecificSchemaDefaults(route);\n\n let query: Record<string, string | string[]> | undefined;\n if (route.queryParamSchema) {\n const generated = generateValidDataFromSchema(route.queryParamSchema) as Record<string, unknown>;\n query = convertQueryValues({\n ...generated,\n ...(schemaDefaults.query ?? {}),\n ...(pathDefaults.query ?? {}),\n ...(overrides.query ?? {}),\n });\n } else if (overrides.query) {\n query = convertQueryValues(overrides.query);\n }\n\n let body: Record<string, unknown> | undefined;\n if (route.bodySchema) {\n const generated = generateValidDataFromSchema(route.bodySchema) as Record<string, unknown>;\n body = {\n ...generated,\n ...(schemaDefaults.body ?? {}),\n ...(pathDefaults.body ?? {}),\n ...(overrides.body ?? {}),\n };\n } else if (overrides.body) {\n body = { ...overrides.body };\n }\n\n return {\n method,\n path,\n query,\n body,\n };\n}\n\nexport function convertQueryValues(values: Record<string, unknown>): Record<string, string | string[]> {\n const query: Record<string, string | string[]> = {};\n const appendValue = (prefix: string, value: unknown) => {\n if (value === undefined || value === null) return;\n if (Array.isArray(value)) {\n // JSON-encode arrays for complex query params (e.g., tags=[\"tag1\",\"tag2\"])\n // Server uses wrapSchemaForQueryParams which expects JSON strings for complex types\n query[prefix] = JSON.stringify(value);\n return;\n }\n if (value instanceof Date) {\n query[prefix] = value.toISOString();\n return;\n }\n if (typeof value === 'object') {\n // JSON-encode objects for complex query params (e.g., dateRange={\"gte\":\"2024-01-01\"})\n // Server uses wrapSchemaForQueryParams which expects JSON strings for complex types\n query[prefix] = JSON.stringify(value);\n return;\n }\n query[prefix] = convertQueryValue(value);\n };\n\n for (const [key, value] of Object.entries(values)) {\n appendValue(key, value);\n }\n return query;\n}\n\nfunction convertQueryValue(value: unknown): string {\n return String(value);\n}\n\n/**\n * Creates a ReadableStream that emits chunks with sensitive data.\n * This simulates what an agent.stream() call would return with request metadata.\n *\n * @param format - The stream format version ('v1' for legacy, 'v2' for current)\n * @returns A ReadableStream with chunks containing sensitive request data\n */\nexport function createStreamWithSensitiveData(format: 'v1' | 'v2' = 'v2'): ReadableStream {\n const sensitiveRequest = {\n body: JSON.stringify({\n model: 'gpt-4',\n messages: [{ role: 'system', content: 'SECRET_SYSTEM_PROMPT' }],\n tools: [{ name: 'secret_tool', description: 'Internal tool' }],\n }),\n };\n\n const chunks =\n format === 'v2'\n ? [\n {\n type: 'step-start',\n runId: 'run-123',\n from: 'AGENT',\n payload: {\n messageId: 'msg-123',\n request: sensitiveRequest,\n warnings: [],\n },\n },\n { type: 'text-delta', textDelta: 'Hello' },\n {\n type: 'step-finish',\n runId: 'run-123',\n from: 'AGENT',\n payload: {\n messageId: 'msg-123',\n metadata: { request: sensitiveRequest },\n output: {\n text: 'Hello',\n steps: [{ request: sensitiveRequest, response: { id: 'resp-1' } }],\n },\n },\n },\n {\n type: 'finish',\n runId: 'run-123',\n from: 'AGENT',\n payload: {\n messageId: 'msg-123',\n metadata: { request: sensitiveRequest },\n output: {\n text: 'Hello',\n steps: [{ request: sensitiveRequest }],\n },\n },\n },\n ]\n : [\n {\n type: 'step-start',\n messageId: 'msg-123',\n request: sensitiveRequest,\n warnings: [],\n },\n { type: 'text-delta', textDelta: 'Hello' },\n {\n type: 'step-finish',\n finishReason: 'stop',\n request: sensitiveRequest,\n },\n {\n type: 'finish',\n finishReason: 'stop',\n request: sensitiveRequest,\n },\n ];\n\n return new ReadableStream({\n start(controller) {\n for (const chunk of chunks) {\n controller.enqueue(chunk);\n }\n controller.close();\n },\n });\n}\n\n/**\n * Creates a ReadableStream for testing per-chunk serialization error handling\n * (https://github.com/mastra-ai/mastra/issues/17821).\n *\n * Emits three chunks:\n * 1. a chunk whose payload contains a BigInt (not JSON-serializable natively — must be coerced to a string)\n * 2. a chunk that cannot be serialized at all (throwing toJSON — must be skipped without killing the stream)\n * 3. a final chunk that must still be delivered after the unserializable one\n *\n * Use {@link expectSerializedStreamChunks} to assert on the consumed result.\n */\nexport function createStreamWithUnserializableChunk(): ReadableStream {\n return new ReadableStream({\n start(controller) {\n controller.enqueue({ type: 'workflow-step-result', payload: { output: { count: 42n } } });\n controller.enqueue({\n type: 'poison',\n toJSON() {\n throw new Error('cannot serialize');\n },\n });\n controller.enqueue({ type: 'workflow-finish', payload: { workflowStatus: 'success' } });\n controller.close();\n },\n });\n}\n\n/**\n * Asserts the chunks consumed from {@link createStreamWithUnserializableChunk}:\n * BigInt coerced to a string, the poison chunk skipped, and the final chunk delivered.\n */\nexport function expectSerializedStreamChunks(chunks: any[]): void {\n const stepResult = chunks.find(c => c.type === 'workflow-step-result');\n expect(stepResult).toBeDefined();\n expect(stepResult.payload.output).toEqual({ count: '42' });\n\n expect(chunks.find(c => c.type === 'poison')).toBeUndefined();\n\n const finish = chunks.find(c => c.type === 'workflow-finish');\n expect(finish, 'chunks after an unserializable chunk must still be delivered').toBeDefined();\n expect(finish.payload.workflowStatus).toBe('success');\n}\n\n/**\n * Helper to consume a stream and parse SSE chunks.\n * Reads all chunks from a stream and parses them from SSE format.\n *\n * @param stream - The ReadableStream to consume (typically response.body)\n * @returns Array of parsed JSON objects from the SSE data lines\n */\nexport async function consumeSSEStream(stream: ReadableStream<Uint8Array> | null): Promise<any[]> {\n if (!stream) return [];\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n const chunks: any[] = [];\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const text = decoder.decode(value);\n // Parse SSE format: \"data: {...}\\n\\n\"\n const lines = text.split('\\n');\n for (const line of lines) {\n if (line.startsWith('data: ') && line !== 'data: [DONE]') {\n try {\n chunks.push(JSON.parse(line.slice(6)));\n } catch {\n // Skip non-JSON lines\n }\n }\n }\n }\n\n return chunks;\n}\n","import { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport { handleError } from '@mastra/server/handlers/error';\nimport { createRoute, HTTPException, SERVER_ROUTES } from '@mastra/server/server-adapter';\nimport type { ServerRoute } from '@mastra/server/server-adapter';\nimport { describe, it, expect, beforeEach } from 'vitest';\nimport { z } from 'zod';\nimport { z as z3 } from 'zod/v3';\n\nimport { createRouteTestSuite } from './route-test-suite';\nimport { expectValidSchema } from './route-test-utils';\nimport { buildRouteRequest, createDefaultTestContext, parseDatesInResponse } from './test-helpers';\nimport type { AdapterTestContext, AdapterTestSuiteConfig, HttpRequest } from './test-helpers';\n\n/**\n * Creates a standardized integration test suite for server adapters (Express/Hono)\n *\n * Tests the complete HTTP request/response cycle:\n * - Parameter extraction from URL/query/body\n * - Schema validation\n * - Handler execution\n * - Response formatting\n *\n * Uses auto-generated test data from route schemas.\n * For specific test scenarios, write additional tests outside the factory.\n */\nexport function createRouteAdapterTestSuite(config: AdapterTestSuiteConfig) {\n const { suiteName = 'Route Adapter Integration', setupAdapter, executeHttpRequest, createTestContext } = config;\n\n describe('Route Validation', () => {\n createRouteTestSuite({\n routes: SERVER_ROUTES,\n });\n });\n\n describe(suiteName, () => {\n let context: AdapterTestContext;\n let app: any;\n let setup: Awaited<ReturnType<typeof setupAdapter>>;\n\n beforeEach(async () => {\n // Create test context - use provided or default\n if (createTestContext) {\n const result = createTestContext();\n context = result instanceof Promise ? await result : result;\n } else {\n context = await createDefaultTestContext();\n }\n\n // Setup adapter and app\n setup = await setupAdapter(context);\n app = setup.app;\n });\n\n if (config.supportsPostQueryRequestContext) {\n it('merges query requestContext into POST route handlers', async () => {\n await setup.adapter.registerRoute(app, {\n method: 'POST',\n path: '/test/query-request-context',\n responseType: 'json',\n bodySchema: z.object({ data: z.string() }),\n handler: async ({ requestContext }: { requestContext?: { get: (key: string) => unknown } }) => ({\n userId: requestContext?.get('userId'),\n }),\n });\n\n const response = await executeHttpRequest(app, {\n method: 'POST',\n path: '/api/test/query-request-context',\n query: { requestContext: JSON.stringify({ userId: 'query-user-123' }) },\n body: { data: 'test' },\n });\n\n expect(response.status).toBe(200);\n expect(response.data).toEqual({ userId: 'query-user-123' });\n });\n }\n\n it('ignores special object keys in query params while preserving legitimate params', async () => {\n await setup.adapter.registerRoute(app, {\n method: 'GET',\n path: '/test/query-special-keys',\n responseType: 'json',\n handler: async (params: any) => ({\n filter: typeof params.filter === 'string' ? JSON.parse(params.filter) : null,\n tag: params.tag ?? null,\n keys: Object.keys(params).filter(\n k =>\n ![\n 'mastra',\n 'requestContext',\n 'tools',\n 'taskStore',\n 'abortSignal',\n 'registeredTools',\n 'routePrefix',\n 'request',\n ].includes(k),\n ),\n }),\n });\n\n const response = await executeHttpRequest(app, {\n method: 'GET',\n path: '/api/test/query-special-keys',\n query: Object.fromEntries([\n // Keys that must never be written onto parsed objects\n ['__proto__[polluted]', 'yes'],\n ['constructor[prototype]', 'yes'],\n ['prototype[x]', 'yes'],\n ['filter[__proto__]', 'yes'],\n // Legitimate params alongside them\n ['filter[status]', 'active'],\n ['tag', ['a', 'b']],\n ['page', '2'],\n ]),\n });\n\n expect(response.status).toBe(200);\n const data = response.data as any;\n // Bracket-notation groups still reconstruct as before\n expect(data.filter).toEqual({ status: 'active' });\n // Repeated keys still arrive (as an array where the framework preserves\n // them; some frameworks collapse them to the last value — both are the\n // pre-existing behavior and must not change)\n const tags = Array.isArray(data.tag) ? data.tag : [data.tag];\n expect(tags).toContain('b');\n // Special keys are dropped, not parsed\n expect(data.keys).not.toContain('__proto__');\n expect(data.keys).not.toContain('constructor');\n expect(data.keys).not.toContain('prototype');\n // The process-wide Object.prototype must be untouched\n expect(({} as any).polluted).toBeUndefined();\n });\n\n describe.each([\n {\n version: 'v3',\n recordSchema: z3.record(z3.string(), z3.string()),\n objectSchema: z3.object({ limit: z3.number().default(10) }),\n },\n {\n version: 'v4',\n recordSchema: z.record(z.string(), z.string()),\n objectSchema: z.object({ limit: z.number().default(10) }),\n },\n ])('Zod $version record body validation', ({ recordSchema, objectSchema }) => {\n beforeEach(async () => {\n await setup.adapter.registerRoute(app, {\n method: 'DELETE',\n path: '/test/record-body',\n responseType: 'json',\n bodySchema: recordSchema,\n handler: async () => ({ success: true }),\n });\n await setup.adapter.registerRoute(app, {\n method: 'DELETE',\n path: '/test/object-body',\n responseType: 'json',\n bodySchema: objectSchema,\n handler: async ({ limit }: { limit: number }) => ({ limit }),\n });\n });\n\n it('does not convert missing record bodies to empty objects', async () => {\n const response = await executeHttpRequest(app, { method: 'DELETE', path: '/api/test/record-body' });\n // Some framework parsers already supply {} before adapter validation runs.\n const alreadyNormalized = config.emptyBodyNormalization?.withoutContentType === 'empty-object';\n expect(response.status).toBe(alreadyNormalized ? 200 : 400);\n if (!alreadyNormalized) {\n expect(response.data).toMatchObject({ error: 'Invalid request body', issues: [{ field: 'root' }] });\n }\n });\n\n it('accepts explicitly empty record bodies', async () => {\n const response = await executeHttpRequest(app, { method: 'DELETE', path: '/api/test/record-body', body: {} });\n expect(response.status).toBe(200);\n expect(response.data).toEqual({ success: true });\n });\n\n it('keeps bodyless object field defaults', async () => {\n const response = await executeHttpRequest(app, { method: 'DELETE', path: '/api/test/object-body' });\n expect(response.status).toBe(200);\n expect(response.data).toEqual({ limit: 10 });\n });\n });\n\n describe('Whole-body defaults over HTTP', () => {\n const normalization = config.emptyBodyNormalization ?? {\n withoutContentType: 'undefined',\n withJsonContentType: 'undefined',\n };\n\n beforeEach(async () => {\n await setup.adapter.registerRoute(\n app,\n createRoute({\n method: 'POST',\n path: '/test/root-default',\n responseType: 'json',\n bodySchema: z.object({ marker: z.string().optional() }).default({ marker: 'root-default' }),\n handler: async ({ marker }) => ({ marker }),\n }),\n );\n });\n\n it.each([\n {\n label: 'omitted body without Content-Type',\n body: undefined,\n headers: undefined,\n normalized: normalization.withoutContentType,\n },\n {\n label: 'zero-byte JSON body',\n body: undefined,\n headers: { 'Content-Type': 'application/json' },\n normalized: normalization.withJsonContentType,\n },\n {\n label: 'explicit empty JSON object',\n body: {},\n headers: { 'Content-Type': 'application/json' },\n normalized: 'empty-object',\n },\n ])('$label respects framework normalization', async ({ body, headers, normalized }) => {\n const response = await executeHttpRequest(app, {\n method: 'POST',\n path: '/api/test/root-default',\n body,\n headers,\n });\n if (normalized === 'empty-string') {\n expect(response.status).toBe(400);\n expect(response.data).toEqual({\n error: 'Invalid request body',\n issues: [{ field: 'root', message: expect.stringContaining('string') }],\n });\n } else {\n expect(response.status).toBe(200);\n expect(response.data).toEqual(normalized === 'undefined' ? { marker: 'root-default' } : {});\n }\n });\n });\n\n describe('Scalar JSON body validation', () => {\n beforeEach(async () => {\n const route = createRoute({\n method: 'DELETE',\n path: '/test/scalar-body',\n responseType: 'json',\n bodySchema: z\n .union([z.null(), z.literal(false), z.literal(0), z.literal('')])\n .transform(value => ({ value })),\n handler: async ({ value }) => ({ value }),\n onValidationError: () => ({ status: 400, body: { error: 'Scalar schema rejected body' } }),\n });\n await setup.adapter.registerRoute(app, route);\n });\n it.each([null, false, 0, ''])('validates scalar JSON through the route schema: %j', async body => {\n const accepted = await executeHttpRequest(app, {\n method: 'DELETE',\n path: '/api/test/scalar-body',\n body,\n });\n expect(accepted.status).toBe(200);\n expect(accepted.data).toEqual({ value: body });\n });\n it('returns the route validation response for an invalid scalar', async () => {\n const rejected = await executeHttpRequest(app, {\n method: 'DELETE',\n path: '/api/test/scalar-body',\n body: true,\n });\n expect(rejected.status).toBe(400);\n expect(rejected.data).toEqual({ error: 'Scalar schema rejected body' });\n });\n });\n\n describe.each(['POST', 'PUT', 'PATCH', 'DELETE'] as const)('%s required body validation', method => {\n beforeEach(async () => {\n await setup.adapter.registerRoute(\n app,\n createRoute({\n method,\n path: '/test/required-body',\n responseType: 'json',\n bodySchema: z.object({ itemIds: z.array(z.string().min(1)).min(1) }),\n handler: async ({ itemIds }) => ({ itemIds }),\n onValidationError: () => ({ status: 400, body: { error: 'Required schema rejected body' } }),\n }),\n );\n await setup.adapter.registerRoute(\n app,\n createRoute({\n method,\n path: '/test/optional-body',\n responseType: 'json',\n bodySchema: z.object({ name: z.string().optional(), limit: z.number().default(10) }),\n handler: async ({ limit }) => ({ limit }),\n }),\n );\n });\n\n it.each([undefined, null, false, 0, '', {}, { itemIds: [] }, { itemIds: [''] }])(\n 'rejects missing or invalid required input %#',\n async body => {\n const response = await executeHttpRequest(app, {\n method,\n path: '/api/test/required-body',\n body,\n });\n expect(response.status).toBe(400);\n expect(response.data).toEqual({ error: 'Required schema rejected body' });\n },\n );\n\n it('passes valid required input to the handler', async () => {\n const body = { itemIds: ['item-1'] };\n const response = await executeHttpRequest(app, {\n method,\n path: '/api/test/required-body',\n body,\n });\n expect(response.status).toBe(200);\n expect(response.data).toEqual(body);\n });\n\n it('applies field defaults when the body is omitted', async () => {\n const response = await executeHttpRequest(app, {\n method,\n path: '/api/test/optional-body',\n });\n expect(response.status).toBe(200);\n expect(response.data).toEqual({ limit: 10 });\n });\n });\n\n it.each([\n { body: {}, field: 'itemIds' },\n { body: { itemIds: [''] }, field: 'itemIds.0' },\n ])('returns standard validation issues for $field', async ({ body, field }) => {\n await setup.adapter.registerRoute(\n app,\n createRoute({\n method: 'DELETE',\n path: '/test/default-validation-error',\n responseType: 'json',\n bodySchema: z.object({ itemIds: z.array(z.string().min(1)).min(1) }),\n handler: async ({ itemIds }) => ({ itemIds }),\n }),\n );\n const response = await executeHttpRequest(app, {\n method: 'DELETE',\n path: '/api/test/default-validation-error',\n body,\n });\n expect(response.status).toBe(400);\n expect(response.data).toEqual({\n error: 'Invalid request body',\n issues: [{ field, message: expect.any(String) }],\n });\n });\n\n it('preserves bodyless create-run requests with optional fields', async () => {\n const response = await executeHttpRequest(app, {\n method: 'POST',\n path: '/api/workflows/test-workflow/create-run',\n });\n expect(response.status).toBe(200);\n expect(response.data).toMatchObject({ runId: expect.any(String) });\n });\n\n // Test deprecated routes separately - just verify they're marked correctly\n const deprecatedRoutes = SERVER_ROUTES.filter(r => r.deprecated);\n\n // Group deprecated routes by first path segment\n const deprecatedByCategory = deprecatedRoutes.reduce(\n (acc, route) => {\n const category = route.path.split('/')[1] || 'root';\n if (!acc[category]) acc[category] = [];\n acc[category].push(route);\n return acc;\n },\n {} as Record<string, typeof deprecatedRoutes>,\n );\n\n Object.entries(deprecatedByCategory).forEach(([category, routes]) => {\n describe(category, () => {\n routes.forEach(route => {\n const testName = `${route.method} ${route.path}`;\n describe(testName, () => {\n it('should be marked as deprecated', () => {\n expect(route.deprecated).toBe(true);\n expect(route.openapi?.deprecated).toBe(true);\n });\n });\n });\n });\n });\n\n // Test non-deprecated routes with full test suite\n // Skip MCP transport routes (mcp-http, mcp-sse) - they require MCP protocol handling\n // and are tested separately via mcp-transport-test-suite\n // Skip auth routes that require specific providers (SSO, credentials) - they return 404\n // when providers aren't configured, which is expected behavior\n // Note: Route paths in SERVER_ROUTES don't include /api prefix\n const authRoutesRequiringProviders = [\n '/auth/sso/login',\n '/auth/sso/callback',\n '/auth/credentials/sign-in',\n '/auth/credentials/sign-up',\n '/auth/refresh',\n // Requires a provider that can actually end a session (destroySession,\n // getClearSessionHeaders, or getLogoutUrl). Without one there is nothing to log out\n // of, so it 404s like /auth/refresh. Per-status behavior is covered in\n // packages/server/src/server/handlers/auth.test.ts.\n '/auth/logout',\n // Requires an authenticated admin caller (MASTRA_USER_PERMISSIONS_KEY is a reserved\n // request-context key set only by the auth middleware) and an RBAC provider with\n // getPermissionsForRole. Per-status behavior is covered in\n // packages/server/src/server/handlers/auth.test.ts.\n '/auth/roles/:roleId/permissions',\n ];\n // Skip routes that require external dependencies (APIs)\n const routesRequiringExternalDeps = [\n // skills-sh routes that require external API calls (GitHub, skills.sh)\n '/workspaces/:workspaceId/skills-sh/search',\n '/workspaces/:workspaceId/skills-sh/popular',\n '/workspaces/:workspaceId/skills-sh/preview',\n '/workspaces/:workspaceId/skills-sh/install',\n '/workspaces/:workspaceId/skills-sh/remove',\n '/workspaces/:workspaceId/skills-sh/update',\n // observational memory routes require OM-enabled agent configuration\n '/memory/observational-memory',\n '/memory/observational-memory/buffer-status',\n // skill publish requires blob storage not available in InMemoryStore\n '/stored/skills/:storedSkillId/publish',\n // POST /stored/agents requires a builder-resolved model policy and a\n // model-allowlist-compatible payload; the generic test suite produces a\n // payload that fails allowlist enforcement. Behavior is covered by\n // packages/server/src/server/handlers/stored-agents.test.ts.\n '/stored/agents',\n // Favorites toggles require an existing stored entity AND an\n // authenticated caller (callerId is read from the auth-middleware\n // request context). Behavior is covered by stored-{agent,skill}-favorites\n // unit tests; the generic test suite can't satisfy both prereqs.\n '/stored/agents/:storedAgentId/favorite',\n '/stored/skills/:storedSkillId/favorite',\n // Change request creation requires a source-control provider that can open\n // PRs; the generic test sutie has no provider. Covered by stored-agents tests.\n '/stored/agents/:storedAgentId/change-request',\n // Builder registry routes that require external API calls + builder config\n '/editor/builder/registries',\n '/editor/builder/registries/:registryId/search',\n '/editor/builder/registries/:registryId/popular',\n '/editor/builder/registries/:registryId/preview',\n '/editor/builder/registries/:registryId/install',\n // Long-lived SSE streams: stay open until the client disconnects, so the\n // test test suite's real-HTTP-server cleanup (server.close awaiting drain)\n // hangs. These routes' behavior is exercised in unit tests.\n '/background-tasks/stream',\n '/agents/:agentId/observe',\n // Recover requires both a durable agent and a persisted workflow run.\n // Its stateful behavior is covered by packages/server/src/server/handlers/agents.test.ts.\n '/agents/:agentId/recover',\n // Reading a submitted plan requires an agent exposing the core submit_plan tool\n // and a workspace filesystem containing the plan. The generic agent has neither;\n // capability, path, and filesystem behavior are covered by plans.test.ts.\n '/agents/:agentId/plans/file',\n // Tool-provider connection routes that require a persisted connection\n // row matching the supplied connectionId. The test suite uses a generic\n // 'test-connection-id' that isn't seeded, so the fail-closed ownership\n // guard returns 403. Behavior is covered by\n // packages/server/src/server/handlers/tool-providers.test.ts.\n '/tool-providers/:providerId/connections/:connectionId',\n '/tool-providers/:providerId/connections/:connectionId/usage',\n // Tool-provider authorize + connection-status routes require a real\n // OAuth provider config; the generic test suite produces a payload the\n // mock provider can't authorize. Covered by tool-providers.test.ts.\n '/tool-providers/:providerId/authorize',\n '/tool-providers/:providerId/connection-status',\n // Tool-provider auth-status requires a live provider auth lookup that\n // the mock provider doesn't implement. Covered by tool-providers.test.ts.\n '/tool-providers/:providerId/auth-status/:authId',\n // Tool-provider connections list relies on storage rows being seeded\n // for the test author. Covered by tool-providers.test.ts.\n '/tool-providers/:providerId/connections',\n // Experiment deletion requires a persisted experiment matching the generated\n // experimentId. The generic test context does not seed dataset storage;\n // deletion behavior is covered by datasets.test.ts.\n '/experiments/:experimentId',\n ];\n // Routes under these prefixes are excluded (e.g. /datasets needs a datasets storage domain)\n const excludedPrefixes = [\n '/datasets',\n // Agent-controller routes resolve a registered AgentController via\n // mastra.getAgentController(id) and operate on a live session keyed by\n // resourceId. The generic test context registers no controller, so every\n // route fails closed with 404. Behavior is covered by\n // packages/server/src/server/handlers/agent-controller.test.ts.\n '/agent-controller',\n ];\n const isExcluded = (r: ServerRoute) =>\n r.deprecated ||\n r.responseType === 'mcp-http' ||\n r.responseType === 'mcp-sse' ||\n authRoutesRequiringProviders.includes(r.path) ||\n routesRequiringExternalDeps.includes(r.path) ||\n excludedPrefixes.some(prefix => r.path.startsWith(prefix));\n const activeRoutes = SERVER_ROUTES.filter(r => !isExcluded(r));\n\n // Group routes by first path segment (e.g., /agents/:id/tools -> 'agents')\n const routesByCategory = activeRoutes.reduce(\n (acc, route) => {\n const category = route.path.split('/')[1] || 'root';\n if (!acc[category]) acc[category] = [];\n acc[category].push(route);\n return acc;\n },\n {} as Record<string, typeof activeRoutes>,\n );\n\n Object.entries(routesByCategory).forEach(([category, routes]) => {\n describe(category, () => {\n routes.forEach(route => {\n const testName = `${route.method} ${route.path}`;\n describe(testName, () => {\n it('should execute with valid request', async () => {\n // Build HTTP request with auto-generated test data\n const request = buildRouteRequest(route);\n\n // Convert to HttpRequest format\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: request.body,\n };\n\n // Execute through adapter\n const response = await executeHttpRequest(app, httpRequest);\n\n // Validate response\n expect(response.status).toBeLessThan(400);\n\n if (route.responseType === 'json') {\n expect(response.type).toBe('json');\n expect(response.data).toBeDefined();\n\n // Validate response schema (if defined)\n if (route.responseSchema) {\n const parsedData = parseDatesInResponse(response.data, route.responseSchema);\n expectValidSchema(route.responseSchema, parsedData);\n }\n\n // Verify JSON is serializable (no circular refs, functions, etc)\n expect(() => JSON.stringify(response.data)).not.toThrow();\n } else if (route.responseType === 'stream') {\n expect(response.type).toBe('stream');\n expect(response.stream).toBeDefined();\n\n // Verify stream is consumable (has getReader or is async iterable)\n const hasReader = response.stream && typeof (response.stream as any).getReader === 'function';\n const isAsyncIterable =\n response.stream &&\n typeof (response.stream as AsyncIterable<unknown>)[Symbol.asyncIterator] === 'function';\n expect(hasReader || isAsyncIterable).toBe(true);\n }\n });\n\n // Error handling tests for routes with entity IDs\n if (route.path.includes(':agentId')) {\n it('should return 404 when agent not found', async () => {\n // Build request with non-existent agent\n const request = buildRouteRequest(route, {\n pathParams: { agentId: 'non-existent-agent' },\n });\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: request.body,\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n // Expect 404 status\n expect(response.status).toBe(404);\n });\n }\n\n if (route.path.includes(':workflowId')) {\n it('should return 404 when workflow not found', async () => {\n const request = buildRouteRequest(route, {\n pathParams: { workflowId: 'non-existent-workflow' },\n });\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: request.body,\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n expect(response.status).toBe(404);\n });\n }\n\n if (route.path.includes(':backgroundTaskId')) {\n it('should return 404 when background task not found', async () => {\n const request = buildRouteRequest(route, {\n pathParams: { backgroundTaskId: 'non-existent-background-task' },\n });\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: request.body,\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n expect(response.status).toBe(404);\n });\n }\n\n // MCP server 404 tests\n if (route.path.includes(':serverId')) {\n it('should return 404 when MCP server not found (via :serverId)', async () => {\n const request = buildRouteRequest(route, {\n pathParams: { serverId: 'non-existent-server' },\n });\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: request.body,\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n expect(response.status).toBe(404);\n });\n }\n\n // MCP v0 server detail 404 test (uses :id instead of :serverId)\n if (route.path.includes('/mcp/v0/servers/:id')) {\n it('should return 404 when MCP server not found (via :id)', async () => {\n const request = buildRouteRequest(route, {\n pathParams: { id: 'non-existent-server' },\n });\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: request.body,\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n expect(response.status).toBe(404);\n });\n }\n\n // Processor 404 tests\n if (route.path.includes(':processorId')) {\n it('should return 404 when processor not found', async () => {\n const request = buildRouteRequest(route, {\n pathParams: { processorId: 'non-existent-processor' },\n });\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: request.body,\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n expect(response.status).toBe(404);\n });\n }\n\n // Stream consumption test\n if (route.responseType === 'stream') {\n it('should be consumable via stream reader', async () => {\n const request = buildRouteRequest(route);\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: request.body,\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n expect(response.status).toBeLessThan(400);\n expect(response.stream).toBeDefined();\n\n // Try to consume the stream\n if (typeof (response.stream as any).getReader === 'function') {\n // Web Streams API\n const reader = (response.stream as ReadableStream).getReader();\n const firstChunk = await reader.read();\n expect(firstChunk).toBeDefined();\n // Don't validate chunk structure - that's handler's job\n reader.releaseLock();\n } else if (typeof (response.stream as AsyncIterable<unknown>)[Symbol.asyncIterator] === 'function') {\n // Async iterable\n const iterator = (response.stream as AsyncIterable<unknown>)[Symbol.asyncIterator]();\n const firstChunk = await iterator.next();\n expect(firstChunk).toBeDefined();\n }\n });\n }\n\n // Schema validation tests - only for routes with query or body schemas\n if (route.queryParamSchema || route.bodySchema) {\n it('should return 400 when schema validation fails', async () => {\n const request = buildRouteRequest(route);\n\n let httpRequest: HttpRequest;\n\n if (route.queryParamSchema) {\n // Add invalid query param (add an object where string/number expected)\n httpRequest = {\n method: request.method,\n path: request.path,\n query: {\n ...(request.query || {}),\n invalidQueryParam: { nested: 'object' } as any,\n },\n body: request.body,\n };\n } else if (route.bodySchema) {\n // Keep valid request but add an invalid field with wrong type\n httpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: {\n ...(typeof request.body === 'object' && request.body !== null ? request.body : {}),\n invalidBodyField: { deeply: { nested: 'object' } },\n },\n };\n } else {\n // Shouldn't happen, but fallback\n httpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: request.body,\n };\n }\n\n const response = await executeHttpRequest(app, httpRequest);\n\n // Routes may use the shared 400 response or a route-specific 422 response.\n // Lenient schemas may still succeed if they ignore unknown fields.\n expect([200, 201, 400, 422]).toContain(response.status);\n\n if (response.status === 400 || response.status === 422) {\n expect(response.type).toBe('json');\n\n // Verify error response has helpful structure\n const errorData = response.data as any;\n expect(errorData).toBeDefined();\n expect(errorData.error || errorData.message || errorData.details).toBeDefined();\n }\n });\n }\n\n // RequestContext tests - test for POST/PUT routes that accept body\n if (['POST', 'PUT'].includes(route.method) && route.bodySchema) {\n it('should accept requestContext in body', async () => {\n const request = buildRouteRequest(route);\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: {\n ...(typeof request.body === 'object' && request.body !== null ? request.body : {}),\n requestContext: { userId: 'test-user-123', sessionId: 'session-456' },\n },\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n // Should succeed - requestContext is optional and should not cause errors\n expect(response.status).toBeLessThan(500);\n });\n }\n\n // Body field spreading test - for POST/PUT routes with body\n const bodySchema = route.bodySchema;\n if (['POST', 'PUT'].includes(route.method) && bodySchema) {\n it('should spread body fields to handler params', async () => {\n const request = buildRouteRequest(route);\n\n // Add a unique field to the body\n const testField = 'testBodyField';\n const testValue = 'testValue123';\n\n const body = {\n ...(typeof request.body === 'object' && request.body !== null ? request.body : {}),\n [testField]: testValue,\n };\n const strictBody = !bodySchema.safeParse(body).success;\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body,\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n if (strictBody) {\n // Strict schemas must surface either the shared or route-specific validation rejection.\n expect([400, 422]).toContain(response.status);\n } else {\n // lenient schema: unknown field must be ignored, request must succeed\n expect(response.status).toBeLessThan(400);\n }\n });\n }\n });\n });\n });\n });\n\n // Additional cross-route tests\n describe('Cross-Route Tests', () => {\n // Test array query parameters for ALL GET routes\n const getRoutes = SERVER_ROUTES.filter(r => r.method === 'GET' && !isExcluded(r));\n getRoutes.forEach(route => {\n it(`should handle array query parameters for ${route.method} ${route.path}`, async () => {\n const request = buildRouteRequest(route);\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: {\n ...(request.query || {}),\n tags: ['tag1', 'tag2', 'tag3'],\n },\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n // Should handle array params without error\n if (response.status >= 500) {\n console.error(`[FAIL] ${route.method} ${route.path} returned ${response.status}`, response.data);\n }\n expect(response.status).toBeLessThan(500);\n });\n });\n\n // Test error response structure for ALL routes with agentId\n const agentRoutes = SERVER_ROUTES.filter(r => r.path.includes(':agentId') && !r.deprecated);\n agentRoutes.forEach(route => {\n it(`should return valid error response structure for ${route.method} ${route.path}`, async () => {\n const request = buildRouteRequest(route, {\n pathParams: { agentId: 'non-existent-agent-error-test' },\n });\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: request.body,\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n expect(response.status).toBe(404);\n expect(response.type).toBe('json');\n\n // Verify error has a structured format\n const errorData = response.data as any;\n expect(errorData).toBeDefined();\n\n // Should have at least one of these error fields\n const hasErrorField =\n errorData.error !== undefined ||\n errorData.message !== undefined ||\n errorData.details !== undefined ||\n errorData.statusCode !== undefined;\n\n expect(hasErrorField).toBe(true);\n });\n });\n\n // Test empty body for ALL POST routes with body schema\n const postRoutesWithBody = SERVER_ROUTES.filter(r => r.method === 'POST' && r.bodySchema && !isExcluded(r));\n postRoutesWithBody.forEach(route => {\n it(`should handle empty body for ${route.method} ${route.path}`, async () => {\n const request = buildRouteRequest(route);\n\n const httpRequest: HttpRequest = {\n method: request.method,\n path: request.path,\n query: request.query,\n body: {}, // Empty body - missing required fields\n };\n\n const response = await executeHttpRequest(app, httpRequest);\n\n // Should return the shared or route-specific validation response for missing fields\n // (or 200/201 if all fields are optional).\n expect([200, 201, 400, 422]).toContain(response.status);\n\n if (response.status === 400 || response.status === 422) {\n expect(response.type).toBe('json');\n const errorData = response.data as any;\n expect(errorData).toBeDefined();\n // Verify error response has helpful structure when validation is explicit\n if (!(errorData.error || errorData.message || errorData.details)) {\n console.warn(`[WARN] ${route.method} ${route.path} 400 response missing error fields`, errorData);\n }\n }\n });\n });\n });\n\n describe('Custom HTTPException responses', () => {\n async function setupCustomErrorRoutes() {\n let handlerCalls = 0;\n const routes: ServerRoute<any, any, any>[] = [\n {\n method: 'GET',\n path: '/custom/http-error-json',\n responseType: 'json',\n handler: async () => {\n handlerCalls++;\n throw new HTTPException(409, {\n res: Response.json(\n { code: 'TRACE_QUERY_CURSOR_CONFLICT', message: 'The cursor does not match the query' },\n { headers: { 'X-Trace-Error': 'cursor' } },\n ),\n });\n },\n },\n {\n method: 'GET',\n path: '/custom/http-error-text',\n responseType: 'json',\n handler: async () => {\n handlerCalls++;\n throw new HTTPException(418, {\n res: new Response('custom text', {\n headers: { 'Content-Type': 'text/custom', 'X-Custom-Error': 'true' },\n }),\n });\n },\n },\n {\n method: 'GET',\n path: '/custom/http-error-fallback',\n responseType: 'json',\n handler: async () => {\n handlerCalls++;\n throw new HTTPException(404, { message: 'Legacy fallback' });\n },\n },\n ];\n const mutableServerRoutes = SERVER_ROUTES as ServerRoute[];\n const originalLength = mutableServerRoutes.length;\n mutableServerRoutes.push(...routes);\n try {\n const setup = await setupAdapter(await createDefaultTestContext());\n return { app: setup.app, getHandlerCalls: () => handlerCalls };\n } finally {\n mutableServerRoutes.splice(originalLength);\n }\n }\n\n it('preserves an attached JSON response and headers', async () => {\n const custom = await setupCustomErrorRoutes();\n\n const response = await executeHttpRequest(custom.app, {\n method: 'GET',\n path: '/api/custom/http-error-json',\n });\n\n expect(response.status).toBe(409);\n expect(response.headers['content-type']).toContain('application/json');\n expect(response.headers['x-trace-error']).toBe('cursor');\n expect(response.data).toEqual({\n code: 'TRACE_QUERY_CURSOR_CONFLICT',\n message: 'The cursor does not match the query',\n });\n expect(custom.getHandlerCalls()).toBe(1);\n });\n\n it('preserves an attached text response without JSON wrapping', async () => {\n const custom = await setupCustomErrorRoutes();\n\n const response = await executeHttpRequest(custom.app, {\n method: 'GET',\n path: '/api/custom/http-error-text',\n });\n\n expect(response.status).toBe(418);\n expect(response.headers['content-type']).toContain('text/custom');\n expect(response.headers['x-custom-error']).toBe('true');\n expect(response.data).toBe('custom text');\n expect(custom.getHandlerCalls()).toBe(1);\n });\n\n it('retains the JSON fallback for message-only HTTP exceptions', async () => {\n const custom = await setupCustomErrorRoutes();\n\n const response = await executeHttpRequest(custom.app, {\n method: 'GET',\n path: '/api/custom/http-error-fallback',\n });\n\n expect(response.status).toBe(404);\n expect(response.data).toEqual({ error: 'Legacy fallback' });\n expect(custom.getHandlerCalls()).toBe(1);\n });\n });\n\n describe('Run claim conflict responses (#27638)', () => {\n // No model is needed: this regression is at the handler-to-HTTP serialization boundary.\n it.each([\n 'AGENT_RESUME_ALREADY_CLAIMED',\n 'WORKFLOW_RESUME_ALREADY_CLAIMED',\n 'AGENT_RESUME_RUN_NOT_SUSPENDED',\n 'WORKFLOW_RUN_NOT_SUSPENDED',\n 'WORKFLOW_TIME_TRAVEL_ALREADY_CLAIMED',\n 'WORKFLOW_TIME_TRAVEL_RUN_RUNNING',\n ] as const)('lets clients identify %s without matching message text', async code => {\n const error = new MastraError(\n { id: code, domain: ErrorDomain.MASTRA_WORKFLOW, category: ErrorCategory.USER },\n 'Run conflict',\n );\n const route: ServerRoute = {\n method: 'POST',\n path: '/test/run-claim-conflict',\n responseType: 'json',\n handler: async () => handleError(error, 'Unable to resume'),\n };\n const mutableServerRoutes = SERVER_ROUTES as ServerRoute[];\n const originalLength = mutableServerRoutes.length;\n mutableServerRoutes.push(route);\n let conflictApp: any;\n try {\n ({ app: conflictApp } = await setupAdapter(context));\n } finally {\n mutableServerRoutes.splice(originalLength);\n }\n\n const response = await executeHttpRequest(conflictApp, {\n method: 'POST',\n path: '/api/test/run-claim-conflict',\n body: {},\n });\n\n expect(response.status).toBe(409);\n expect(response.headers['content-type']).toContain('application/json');\n expect(response.data).toEqual({ error: 'Run conflict', code });\n });\n });\n\n // Route prefix tests\n describe('Route Prefix', () => {\n it('should register routes at prefixed paths without double /api', async () => {\n // Create a new adapter with a custom prefix\n const prefixedSetup = await setupAdapter(context, { prefix: '/v2' });\n const prefixedApp = prefixedSetup.app;\n\n // Request the expected path: /v2/agents (not /v2/api/agents)\n const response = await executeHttpRequest(prefixedApp, {\n method: 'GET',\n path: '/v2/agents',\n });\n\n // Should succeed - routes should be at /v2/agents\n expect(response.status).toBeLessThan(400);\n });\n\n it('should not have routes at double /api path when prefix is set', async () => {\n // Create a new adapter with a custom prefix\n const prefixedSetup = await setupAdapter(context, { prefix: '/v2' });\n const prefixedApp = prefixedSetup.app;\n\n // The buggy path /v2/api/agents should NOT work\n const response = await executeHttpRequest(prefixedApp, {\n method: 'GET',\n path: '/v2/api/agents',\n });\n\n // Should return 404 - this path should not exist\n expect(response.status).toBe(404);\n });\n\n it('should normalize prefix with trailing slash', async () => {\n // Create adapter with trailing slash in prefix\n const prefixedSetup = await setupAdapter(context, { prefix: '/mastra/' });\n const prefixedApp = prefixedSetup.app;\n\n // Request should work at normalized path /mastra/agents (not /mastra//agents)\n const response = await executeHttpRequest(prefixedApp, {\n method: 'GET',\n path: '/mastra/agents',\n });\n\n // Should succeed - trailing slash should be normalized\n expect(response.status).toBeLessThan(400);\n });\n\n it('should normalize prefix without leading slash', async () => {\n // Create adapter without leading slash in prefix\n const prefixedSetup = await setupAdapter(context, { prefix: 'mastra' });\n const prefixedApp = prefixedSetup.app;\n\n // Request should work at normalized path /mastra/agents\n const response = await executeHttpRequest(prefixedApp, {\n method: 'GET',\n path: '/mastra/agents',\n });\n\n // Should succeed - leading slash should be added\n expect(response.status).toBeLessThan(400);\n });\n\n it('should not have routes at double-slash path when prefix has trailing slash', async () => {\n // Create adapter with trailing slash in prefix\n const prefixedSetup = await setupAdapter(context, { prefix: '/mastra/' });\n const prefixedApp = prefixedSetup.app;\n\n // The double-slash path /mastra//agents should NOT work\n const response = await executeHttpRequest(prefixedApp, {\n method: 'GET',\n path: '/mastra//agents',\n });\n\n // Should return 404 - double-slash path should not exist\n expect(response.status).toBe(404);\n });\n });\n });\n}\n","import { Mastra } from '@mastra/core/mastra';\nimport type { MCPServer } from '@mastra/mcp';\nimport { describe, it, expect, beforeEach } from 'vitest';\nimport { createDefaultTestContext } from './test-helpers';\nimport type { AdapterTestContext, AdapterTestSuiteConfig } from './test-helpers';\n\n/**\n * Creates a standardized integration test suite for MCP registry routes\n *\n * Tests the 5 MCP registry routes work correctly with any adapter:\n * - List MCP servers\n * - Get MCP server details\n * - List MCP server tools\n * - Get MCP server tool details\n * - Execute MCP server tool\n *\n * Usage:\n * ```ts\n * describe('Hono MCP Routes', () => {\n * createMCPRouteTestSuite({\n * suiteName: 'Hono Adapter',\n * setupAdapter: async (context) => {\n * const app = new Hono();\n * const adapter = new MastraServer({ app, mastra: context.mastra, ... });\n * await adapter.init(); // Registers context, auth, and all routes\n * return { app, adapter };\n * },\n * executeHttpRequest: async (app, req) => {\n * const res = await app.request(req.path + (req.query ? '?' + new URLSearchParams(req.query).toString() : ''));\n * return { status: res.status, type: 'json', data: await res.json() };\n * }\n * });\n * });\n * ```\n */\nexport function createMCPRouteTestSuite(config: AdapterTestSuiteConfig) {\n const { suiteName = 'MCP Registry Routes Integration', setupAdapter, executeHttpRequest, createTestContext } = config;\n\n describe(suiteName, () => {\n let context: AdapterTestContext;\n let app: any;\n let mcpServer1: MCPServer;\n let mcpServer2: MCPServer;\n\n beforeEach(async () => {\n // Create test context - use provided or default\n if (createTestContext) {\n const result = createTestContext();\n context = result instanceof Promise ? await result : result;\n } else {\n context = await createDefaultTestContext();\n }\n\n const setup = await setupAdapter(context);\n app = setup.app;\n const mastra = setup.adapter.mastra;\n mcpServer1 = mastra.getMCPServerById('test-server-1');\n mcpServer2 = mastra.getMCPServerById('test-server-2');\n }, 30000);\n\n describe('GET /api/mcp/v0/servers', () => {\n it('should list MCP servers', async () => {\n const res = await executeHttpRequest(app, {\n method: 'GET',\n path: '/api/mcp/v0/servers',\n });\n\n expect(res.status).toBe(200);\n expect(res.data).toMatchObject({\n servers: expect.arrayContaining([\n expect.objectContaining({\n name: 'Test Server 1',\n version_detail: expect.objectContaining({\n version: '1.0.0',\n }),\n }),\n expect.objectContaining({\n name: 'Test Server 2',\n version_detail: expect.objectContaining({\n version: '1.1.0',\n }),\n }),\n ]),\n total_count: 2,\n });\n });\n\n it('should handle pagination with page/perPage', async () => {\n const res = await executeHttpRequest(app, {\n method: 'GET',\n path: '/api/mcp/v0/servers',\n query: { perPage: '1', page: '0' },\n });\n\n expect(res.status).toBe(200);\n expect(res.data).toMatchObject({\n servers: expect.any(Array),\n total_count: 2,\n });\n expect((res.data as any).servers).toHaveLength(1);\n expect((res.data as any).next).toContain('perPage=1');\n expect((res.data as any).next).toContain('page=1');\n // Verify the returned server is one of the expected ones\n expect(['Test Server 1', 'Test Server 2']).toContain((res.data as any).servers[0].name);\n });\n\n it('should handle pagination with legacy limit/offset', async () => {\n const res = await executeHttpRequest(app, {\n method: 'GET',\n path: '/api/mcp/v0/servers',\n query: { limit: '1', offset: '0' },\n });\n\n expect(res.status).toBe(200);\n expect(res.data).toMatchObject({\n servers: expect.any(Array),\n total_count: 2,\n });\n expect((res.data as any).servers).toHaveLength(1);\n // Response mirrors request format (legacy limit/offset)\n expect((res.data as any).next).toContain('limit=1');\n expect((res.data as any).next).toContain('offset=1');\n // Verify the returned server is one of the expected ones\n expect(['Test Server 1', 'Test Server 2']).toContain((res.data as any).servers[0].name);\n });\n\n it('should return empty list when no MCP servers registered', async () => {\n // Create a minimal Mastra instance with no MCP servers\n const emptyMastra = new Mastra({});\n\n // Setup adapter with empty Mastra\n const emptySetup = await setupAdapter({\n mastra: emptyMastra,\n tools: {},\n });\n\n const res = await executeHttpRequest(emptySetup.app, {\n method: 'GET',\n path: '/api/mcp/v0/servers',\n });\n\n expect(res.status).toBe(200);\n expect(res.data).toMatchObject({\n servers: [],\n total_count: 0,\n next: null,\n });\n });\n });\n\n describe('GET /api/mcp/v0/servers/:id', () => {\n it('should get server details', async () => {\n const res = await executeHttpRequest(app, {\n method: 'GET',\n path: `/api/mcp/v0/servers/${mcpServer1.id}`,\n });\n\n expect(res.status).toBe(200);\n expect(res.data).toMatchObject({\n id: mcpServer1.id,\n name: 'Test Server 1',\n description: 'Test MCP Server 1',\n version_detail: {\n version: '1.0.0',\n is_latest: true,\n },\n });\n });\n\n it('should return 404 for non-existent server', async () => {\n const res = await executeHttpRequest(app, {\n method: 'GET',\n path: '/api/mcp/v0/servers/non-existent',\n });\n\n expect(res.status).toBe(404);\n expect((res.data as any).error).toContain('not found');\n });\n });\n\n describe('GET /api/mcp/:serverId/tools', () => {\n it('should list server tools', async () => {\n const res = await executeHttpRequest(app, {\n method: 'GET',\n path: `/api/mcp/${mcpServer1.id}/tools`,\n });\n\n expect(res.status).toBe(200);\n expect((res.data as any).tools).toHaveLength(2);\n expect((res.data as any).tools).toEqual(\n expect.arrayContaining([\n expect.objectContaining({ name: 'getWeather' }),\n expect.objectContaining({ name: 'calculate' }),\n ]),\n );\n });\n\n it('should return 404 for non-existent server', async () => {\n const res = await executeHttpRequest(app, {\n method: 'GET',\n path: '/api/mcp/non-existent/tools',\n });\n\n expect(res.status).toBe(404);\n });\n });\n\n describe('GET /api/mcp/:serverId/tools/:toolId', () => {\n it('should get tool details', async () => {\n const res = await executeHttpRequest(app, {\n method: 'GET',\n path: `/api/mcp/${mcpServer1.id}/tools/getWeather`,\n });\n\n expect(res.status).toBe(200);\n expect(res.data).toMatchObject({\n name: 'getWeather',\n description: 'Gets the current weather for a location',\n inputSchema: expect.any(Object),\n });\n });\n\n it('should return 404 for non-existent tool', async () => {\n const res = await executeHttpRequest(app, {\n method: 'GET',\n path: `/api/mcp/${mcpServer1.id}/tools/non-existent`,\n });\n\n expect(res.status).toBe(404);\n });\n });\n\n describe('POST /api/mcp/:serverId/tools/:toolId/execute', () => {\n it('should execute tool', async () => {\n const res = await executeHttpRequest(app, {\n method: 'POST',\n path: `/api/mcp/${mcpServer1.id}/tools/calculate/execute`,\n body: { data: { operation: 'add', a: 5, b: 3 } },\n });\n\n expect(res.status).toBe(200);\n expect((res.data as any).result).toEqual({\n result: 8,\n });\n });\n\n it('should execute tool with location data', async () => {\n const res = await executeHttpRequest(app, {\n method: 'POST',\n path: `/api/mcp/${mcpServer1.id}/tools/getWeather/execute`,\n body: { data: { location: 'San Francisco' } },\n });\n\n expect(res.status).toBe(200);\n expect((res.data as any).result).toMatchObject({\n temperature: 72,\n condition: 'Sunny in San Francisco',\n });\n });\n\n it('should return 404 for non-existent server', async () => {\n const res = await executeHttpRequest(app, {\n method: 'POST',\n path: '/api/mcp/non-existent/tools/calculate/execute',\n body: { data: { operation: 'add', a: 1, b: 2 } },\n });\n\n expect(res.status).toBe(404);\n });\n\n it('should return error for non-existent tool', async () => {\n const res = await executeHttpRequest(app, {\n method: 'POST',\n path: `/api/mcp/${mcpServer1.id}/tools/non-existent/execute`,\n body: { data: {} },\n });\n\n // Current behavior returns 500, ideally should be 404\n expect([404, 500]).toContain(res.status);\n });\n\n it('should handle invalid tool input', async () => {\n const res = await executeHttpRequest(app, {\n method: 'POST',\n path: `/api/mcp/${mcpServer1.id}/tools/calculate/execute`,\n body: { data: { operation: 'invalid', a: 'not-a-number', b: 3 } },\n });\n\n // Input validation may return 400 or 200 with error details depending on implementation\n // Current behavior: zod validation fails during execution, but enum check happens first\n expect([200, 400, 500]).toContain(res.status);\n if (res.status === 200) {\n // If 200, expect error in response body\n expect((res.data as any).error || (res.data as any).result).toBeDefined();\n }\n });\n });\n });\n}\n","import type { ToolsInput } from '@mastra/core/agent';\nimport { MCPServerBase } from '@mastra/core/mcp';\nimport type { MCPServerHTTPOptions, MCPToolExecutionResultV2 } from '@mastra/core/mcp';\nimport { RequestContext } from '@mastra/core/request-context';\nimport { standardSchemaToJSONSchema } from '@mastra/core/schema';\nimport { createTool, isValidationError } from '@mastra/core/tools';\nimport type { InternalCoreTool, MCPToolExecutionContext } from '@mastra/core/tools';\nimport { makeCoreTool } from '@mastra/core/utils';\nimport { z } from 'zod/v4';\n\nconst unavailable = (feature: string) => async (): Promise<never> => {\n throw new Error(`${feature} is not available on a 2026-07-28 server`);\n};\n\n/** The `context.mcp` a 2026-07-28 server builds: the 1.x shape, with server-initiated requests throwing. */\nfunction requestContext2026(): MCPToolExecutionContext {\n const signal = new AbortController().signal;\n return {\n protocolVersion: '2026-07-28',\n extra: {\n signal,\n requestId: 'rest',\n sendNotification: unavailable('extra.sendNotification'),\n sendRequest: unavailable('extra.sendRequest'),\n mcpReq: {\n id: 'rest',\n method: 'tools/call',\n requestState: () => undefined,\n signal,\n send: unavailable('mcpReq.send'),\n notify: unavailable('mcpReq.notify'),\n log: unavailable('mcpReq.log'),\n elicitInput: unavailable('mcpReq.elicitInput'),\n requestSampling: unavailable('mcpReq.requestSampling'),\n },\n },\n elicitation: { sendRequest: unavailable('elicitation.sendRequest') },\n log: async () => {},\n progress: async () => {},\n };\n}\n\n/** Exercises adapter dispatch, not MCP wire-protocol conformance. */\nexport class NativeMCPFixture extends MCPServerBase {\n override readonly mcpVersion = 2 as const;\n constructor() {\n super({\n id: 'native-fixture',\n name: 'Native fixture',\n version: '2.0.0',\n tools: {\n ordinary: createTool({\n id: 'native-fixture-ordinary',\n description: 'Ordinary execution',\n execute: async (_input, context) => ({\n protocolVersion: context.mcp?.protocolVersion ?? null,\n elicitation: await context\n .mcp!.elicitation.sendRequest({ message: 'x', requestedSchema: { type: 'object', properties: {} } })\n .then(\n () => 'answered',\n (error: Error) => error.message,\n ),\n }),\n }),\n interaction: createTool({\n id: 'native-fixture-interaction',\n description: 'Asks for confirmation',\n inputSchema: z.object({}),\n outputSchema: z.number(),\n suspendSchema: z.object({ phase: z.literal('confirm') }),\n resumeSchema: z.object({ confirmed: z.boolean() }),\n execute: async (_input, context) => {\n if (!context.resumeData) {\n await context.suspend?.({ phase: 'confirm' });\n return;\n }\n return 1;\n },\n }),\n },\n });\n }\n\n // Converts tools like the 1.x package does; `context.mcp` flows through CoreToolBuilder.\n convertTools(tools: ToolsInput) {\n const converted: Record<string, InternalCoreTool> = {};\n for (const [name, tool] of Object.entries(tools)) {\n converted[name] = makeCoreTool(tool, {\n name,\n requestContext: new RequestContext(),\n mastra: this.mastra,\n logger: this.logger,\n }) as InternalCoreTool;\n }\n return converted;\n }\n async executeTool(\n toolId: string,\n args: unknown,\n executionContext: Parameters<MCPServerBase['executeTool']>[2] = {},\n ): Promise<MCPToolExecutionResultV2> {\n const tool = this.convertedTools[toolId];\n if (!tool?.execute) throw new Error(`Tool ${toolId} not found`);\n let suspension: { payload: unknown } | undefined;\n const mcp = requestContext2026();\n const output = await tool.execute(args, {\n // Same idiom as the 1.x package: an empty toolCallId keeps CoreToolBuilder on the MCP path.\n toolCallId: '',\n messages: [],\n requestContext: executionContext.requestContext,\n abortSignal: mcp.extra.signal,\n mcp,\n suspend: async (payload: unknown) => void (suspension = { payload }),\n resumeData: executionContext.resumeData,\n suspendPayload: executionContext.suspendPayload,\n });\n if (suspension) {\n const original = this.originalTools[toolId];\n const resumeSchema = original && 'resumeSchema' in original ? original.resumeSchema : undefined;\n return {\n status: 'suspended',\n suspendPayload: suspension.payload,\n resumeSchema: resumeSchema ? standardSchemaToJSONSchema(resumeSchema, { io: 'input' }) : undefined,\n };\n }\n // Core reports invalid input/resume data as a validation-error output (the same\n // object agents see); a 2.x server rejects it like any other failed call.\n if (isValidationError(output)) throw new Error(output.message);\n return { status: 'completed', output };\n }\n\n async startHTTP(options: MCPServerHTTPOptions) {\n options.res.statusCode = 200;\n options.res.setHeader('Content-Type', 'application/json');\n options.res.end(JSON.stringify({ native: true, httpPath: options.httpPath }));\n }\n async startStdio() {}\n async close() {}\n getServerInfo() {\n return {\n id: this.id,\n name: this.name,\n version_detail: { version: this.version, release_date: this.releaseDate, is_latest: this.isLatest },\n };\n }\n getServerDetail() {\n return this.getServerInfo();\n }\n getToolListInfo() {\n return { tools: Object.keys(this.tools()).map(name => ({ name, inputSchema: { type: 'object' } })) };\n }\n getToolInfo(name: string) {\n return this.getToolListInfo().tools.find(tool => tool.name === name);\n }\n async readResource() {\n return { contents: [] };\n }\n async listResources() {\n return { resources: [] };\n }\n}\n","import { Mastra } from '@mastra/core/mastra';\nimport { createTool } from '@mastra/core/tools';\nimport { MCPServer, MCPClient } from '@mastra/mcp';\nimport { describe, it, expect, beforeAll, afterAll } from 'vitest';\nimport { z } from 'zod';\nimport { NativeMCPFixture } from './native-mcp-fixture';\n\n/**\n * Configuration for MCP transport test suite\n */\nexport interface MCPTransportTestConfig {\n /** Name for the test suite */\n suiteName?: string;\n /**\n * Creates an HTTP server for the given Mastra instance.\n * Returns the server and port for testing.\n */\n createServer: (mastra: Mastra) => Promise<{\n /** The HTTP server instance (will be closed in afterAll) */\n server: { close: () => void };\n /** The port the server is listening on */\n port: number;\n }>;\n}\n\n/**\n * Creates a standardized integration test suite for MCP transport routes\n *\n * Tests MCP protocol transport endpoints using MCPClient:\n * - HTTP Transport (POST /api/mcp/:serverId/mcp)\n * - Legacy SSE routes (GET /api/mcp/:serverId/sse, POST /api/mcp/:serverId/messages)\n * are only served for MCP 1.x servers; MCP 2.x instances answer 404.\n *\n * These tests require a real HTTP server because MCPClient drives the\n * self-contained 2026-07-28 request lifecycle over real Streamable HTTP.\n *\n * Usage:\n * ```ts\n * // Hono adapter\n * createMCPTransportTestSuite({\n * suiteName: 'Hono MCP Transport',\n * createServer: async (mastra) => {\n * const app = await createHonoServer(mastra, { tools: {} });\n * const server = serve({ fetch: app.fetch, port: 0 });\n * const address = server.address();\n * const port = typeof address === 'object' ? address.port : 9999;\n * return { server, port };\n * },\n * });\n *\n * // Express adapter\n * createMCPTransportTestSuite({\n * suiteName: 'Express MCP Transport',\n * createServer: async (mastra) => {\n * const app = express();\n * const adapter = new MastraServer({ mastra });\n * adapter.mount(app);\n * const server = app.listen(0);\n * const address = server.address();\n * const port = typeof address === 'object' ? address.port : 9999;\n * return { server, port };\n * },\n * });\n * ```\n */\nexport function createMCPTransportTestSuite(config: MCPTransportTestConfig) {\n const { suiteName = 'MCP Transport Routes', createServer } = config;\n\n const expectTextToolResult = (result: any, expectedPayload: unknown) => {\n expect(result).toBeDefined();\n expect(result).toMatchObject({\n isError: false,\n content: [\n {\n type: 'text',\n },\n ],\n });\n expect(result.content).toHaveLength(1);\n expect(JSON.parse(result.content[0].text)).toEqual(expectedPayload);\n };\n\n describe(suiteName, () => {\n // Test tools - no outputSchema to avoid MCP validation conflicts\n const weatherTool = createTool({\n id: 'getWeather',\n description: 'Gets the current weather for a location',\n inputSchema: z.object({\n location: z.string().describe('The location to get weather for'),\n }),\n execute: async ({ location }) => ({\n temperature: 72,\n condition: `Sunny in ${location}`,\n }),\n });\n\n const calculatorTool = createTool({\n id: 'calculate',\n description: 'Performs basic calculations',\n inputSchema: z.object({\n operation: z.enum(['add', 'subtract', 'multiply', 'divide']),\n a: z.number(),\n b: z.number(),\n }),\n execute: async ({ operation, a, b }) => {\n let result = 0;\n switch (operation) {\n case 'add':\n result = a + b;\n break;\n case 'subtract':\n result = a - b;\n break;\n case 'multiply':\n result = a * b;\n break;\n case 'divide':\n result = a / b;\n break;\n }\n return { result };\n },\n });\n\n let httpServer: { close: () => void };\n let port: number;\n let mcpServer1: MCPServer;\n let mcpServer2: MCPServer;\n let mcpClient: MCPClient;\n let mastra: Mastra;\n\n beforeAll(async () => {\n // Create MCP servers with tools\n mcpServer1 = new MCPServer({\n name: 'server1',\n version: '1.0.0',\n description: 'Test MCP Server 1',\n tools: {\n getWeather: weatherTool,\n calculate: calculatorTool,\n },\n });\n\n mcpServer2 = new MCPServer({\n name: 'server2',\n version: '1.1.0',\n description: 'Test MCP Server 2',\n tools: {},\n });\n\n // Create Mastra instance\n mastra = new Mastra({\n mcpServers: {\n 'test-server-1': mcpServer1,\n 'test-server-2': mcpServer2,\n 'native-fixture': new NativeMCPFixture(),\n },\n });\n\n // Create HTTP server using adapter-specific implementation\n const serverSetup = await createServer(mastra);\n httpServer = serverSetup.server;\n port = serverSetup.port;\n\n // Create MCPClient for transport tests\n mcpClient = new MCPClient({\n servers: {\n server1: {\n url: new URL(`http://localhost:${port}/api/mcp/${mcpServer1.id}/mcp`),\n },\n server2: {\n url: new URL(`http://localhost:${port}/api/mcp/${mcpServer2.id}/mcp`),\n },\n },\n });\n }, 30000);\n\n afterAll(async () => {\n await mcpClient?.disconnect();\n httpServer?.close();\n await mcpServer1?.close();\n await mcpServer2?.close();\n }, 30000);\n\n describe('native MCP v2 adapter dispatch', () => {\n it('dispatches HTTP through the shared adapter path', async () => {\n const response = await fetch(`http://localhost:${port}/api/mcp/native-fixture/mcp`, { method: 'POST' });\n expect(response.status).toBe(200);\n expect(await response.json()).toEqual({ native: true, httpPath: '/api/mcp/native-fixture/mcp' });\n });\n\n it.each([\n { path: 'sse', method: 'GET' },\n { path: 'messages', method: 'POST' },\n ])('rejects the legacy $path route for a native server', async ({ path, method }) => {\n const response = await fetch(`http://localhost:${port}/api/mcp/native-fixture/${path}`, { method });\n expect(response.status).toBe(404);\n });\n\n it('executes ordinary tools with the v2 request context and reports a suspended tool truthfully', async () => {\n const base = `http://localhost:${port}/api/mcp/native-fixture/tools`;\n const init = {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ data: {} }),\n };\n const ordinary = await fetch(`${base}/ordinary/execute`, init);\n expect(ordinary.status).toBe(200);\n expect(await ordinary.json()).toEqual({\n result: {\n protocolVersion: '2026-07-28',\n elicitation: 'elicitation.sendRequest is not available on a 2026-07-28 server',\n },\n });\n const suspended = await fetch(`${base}/interaction/execute`, init);\n expect(suspended.status).toBe(200);\n expect(await suspended.json()).toEqual({\n status: 'suspended',\n suspendPayload: { phase: 'confirm' },\n resumeSchema: expect.objectContaining({ type: 'object', properties: { confirmed: { type: 'boolean' } } }),\n });\n });\n\n it('continues a suspended tool over REST with resumeData and the echoed suspendPayload', async () => {\n const base = `http://localhost:${port}/api/mcp/native-fixture/tools/interaction/execute`;\n const post = (body: unknown) =>\n fetch(base, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) });\n\n const resumed = await post({ data: {}, resumeData: { confirmed: true }, suspendPayload: { phase: 'confirm' } });\n expect(resumed.status).toBe(200);\n expect(await resumed.json()).toEqual({ result: 1 });\n\n // An answer that fails resumeSchema is a failed call, never a completed one.\n const invalid = await post({\n data: {},\n resumeData: { confirmed: 'yes' },\n suspendPayload: { phase: 'confirm' },\n });\n expect(invalid.status).toBe(500);\n expect(await invalid.json()).not.toMatchObject({ status: 'completed' });\n });\n });\n\n describe('HTTP Transport (/api/mcp/:serverId/mcp)', () => {\n describe('Error handling (raw HTTP)', () => {\n it('should return 404 for non-existent server', async () => {\n const res = await fetch(`http://localhost:${port}/api/mcp/non-existent/mcp`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json, text/event-stream',\n },\n body: JSON.stringify({\n jsonrpc: '2.0',\n method: 'initialize',\n params: {\n protocolVersion: '2024-11-05',\n capabilities: {},\n clientInfo: { name: 'test-client', version: '1.0.0' },\n },\n id: 1,\n }),\n });\n\n expect(res.status).toBe(404);\n });\n });\n\n describe('Protocol operations (MCPClient)', () => {\n it('should list tools via MCPClient', async () => {\n const tools = await mcpClient.listTools();\n\n // MCPClient prefixes tool names with server name\n expect(tools['server1_getWeather']).toBeDefined();\n expect(tools['server1_calculate']).toBeDefined();\n });\n\n it('should execute tool via MCPClient', async () => {\n const tools = await mcpClient.listTools();\n const calculateTool = tools['server1_calculate'];\n\n expect(calculateTool).toBeDefined();\n if (!calculateTool) {\n throw new Error('Expected server1_calculate tool');\n }\n expect(calculateTool.execute).toBeDefined();\n\n const result = await calculateTool.execute!({ operation: 'multiply', a: 6, b: 7 }, {} as any);\n\n expectTextToolResult(result, { result: 42 });\n });\n\n it('should execute weather tool via MCPClient', async () => {\n const tools = await mcpClient.listTools();\n const weatherToolInstance = tools['server1_getWeather'];\n\n expect(weatherToolInstance).toBeDefined();\n if (!weatherToolInstance) {\n throw new Error('Expected server1_getWeather tool');\n }\n expect(weatherToolInstance.execute).toBeDefined();\n\n const result = await weatherToolInstance.execute!({ location: 'Austin' }, {} as any);\n\n expectTextToolResult(result, {\n temperature: 72,\n condition: 'Sunny in Austin',\n });\n });\n\n it('should handle multiple MCP servers', async () => {\n const tools = await mcpClient.listTools();\n\n // Server 1 has 2 tools\n expect(tools['server1_getWeather']).toBeDefined();\n expect(tools['server1_calculate']).toBeDefined();\n\n // Server 2 has 0 tools\n const server2Tools = Object.keys(tools).filter(k => k.startsWith('server2_'));\n expect(server2Tools).toHaveLength(0);\n });\n });\n\n describe('Tool execution errors (MCPClient)', () => {\n let failingClient: MCPClient;\n let failingServer: MCPServer;\n let failingMastra: Mastra;\n let failingHttpServer: { close: () => void };\n\n beforeAll(async () => {\n const failingTool = createTool({\n id: 'failingTool',\n description: 'A tool that always throws an error',\n inputSchema: z.object({}),\n execute: async () => {\n throw new Error('Tool execution failed intentionally');\n },\n });\n\n failingServer = new MCPServer({\n name: 'failingServer',\n version: '1.0.0',\n tools: { failingTool },\n });\n\n failingMastra = new Mastra({\n mcpServers: { 'failing-server': failingServer },\n });\n\n const serverSetup = await createServer(failingMastra);\n failingHttpServer = serverSetup.server;\n const failingPort = serverSetup.port;\n\n failingClient = new MCPClient({\n servers: {\n failing: {\n url: new URL(`http://localhost:${failingPort}/api/mcp/${failingServer.id}/mcp`),\n // This test asserts the shape of the server's isError envelope\n // (result.content carries the serialized error), so opt out of the\n // default throw-on-error behavior and resolve with the raw result.\n onToolError: 'return',\n },\n },\n });\n }, 30000);\n\n afterAll(async () => {\n await failingClient?.disconnect();\n failingHttpServer?.close();\n await failingServer?.close();\n }, 30000);\n\n it('should return error when tool execution fails', async () => {\n const tools = await failingClient.listTools();\n const failingTool = tools['failing_failingTool'];\n\n expect(failingTool).toBeDefined();\n if (!failingTool) {\n throw new Error('Expected failing_failingTool tool');\n }\n\n const result = await failingTool.execute!({}, {} as any);\n\n expect(result).toBeDefined();\n expect(result.content).toBeInstanceOf(Array);\n expect(result.content.length).toBeGreaterThan(0);\n\n const errorOutput = result.content[0];\n expect(errorOutput.type).toBe('text');\n\n const errorData = JSON.parse(errorOutput.text);\n expect(errorData.message).toContain('Tool execution failed intentionally');\n expect(errorData.code).toBe('TOOL_EXECUTION_FAILED');\n });\n });\n });\n\n describe('SSE Transport (/api/mcp/:serverId/sse)', () => {\n describe('Error handling (raw HTTP)', () => {\n it('should return 404 for non-existent server on GET /sse', async () => {\n const res = await fetch(`http://localhost:${port}/api/mcp/non-existent/sse`);\n expect(res.status).toBe(404);\n });\n\n it('should return 404 for non-existent server on POST /messages', async () => {\n const res = await fetch(`http://localhost:${port}/api/mcp/non-existent/messages`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n method: 'test',\n id: 1,\n }),\n });\n\n expect(res.status).toBe(404);\n });\n });\n\n describe('MCP 2.x servers (MCPClient)', () => {\n it('does not serve the legacy SSE transport for a 2.x MCPServer', async ctx => {\n if ((mcpServer1 as { mcpVersion?: number }).mcpVersion !== 2) ctx.skip();\n const res = await fetch(`http://localhost:${port}/api/mcp/${mcpServer1.id}/sse`);\n expect(res.status).toBe(404);\n\n const messages = await fetch(`http://localhost:${port}/api/mcp/${mcpServer1.id}/messages`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ jsonrpc: '2.0', method: 'tools/list', id: 1 }),\n });\n expect(messages.status).toBe(404);\n });\n\n it('fails to connect through the SSE URL without downgrading', async ctx => {\n if ((mcpServer1 as { mcpVersion?: number }).mcpVersion !== 2) ctx.skip();\n const sseClient = new MCPClient({\n id: `sse-rejection-${port}`,\n servers: {\n server1: { url: new URL(`http://localhost:${port}/api/mcp/${mcpServer1.id}/sse`) },\n },\n });\n try {\n const { tools, errors } = await sseClient.listToolsWithErrors();\n expect(tools).toEqual({});\n expect(errors.server1).toContain('Failed to connect to MCP server server1');\n } finally {\n await sseClient.disconnect();\n }\n });\n });\n });\n });\n}\n","import type { ServerRoute } from '@mastra/server/server-adapter';\nimport { describe, it, expect, beforeEach, afterEach } from 'vitest';\nimport { createDefaultTestContext } from './test-helpers';\nimport type { AdapterTestContext } from './test-helpers';\n\n/**\n * Configuration for multipart FormData test suite\n */\nexport interface MultipartTestSuiteConfig {\n /** Name for the test suite */\n suiteName?: string;\n\n /**\n * Setup adapter and app for testing\n */\n setupAdapter: (\n context: AdapterTestContext,\n options?: { bodyLimitOptions?: { maxSize: number; onError: (err: any) => any } },\n ) => { adapter: any; app: any } | Promise<{ adapter: any; app: any }>;\n\n /**\n * Start a test server and return its base URL\n * The returned cleanup function should close the server\n */\n startServer: (app: any) => Promise<{ baseUrl: string; cleanup: () => Promise<void> }>;\n\n /**\n * Register a route with the adapter\n */\n registerRoute: (adapter: any, app: any, route: ServerRoute, options?: { prefix?: string }) => Promise<void>;\n\n /**\n * Get the context middleware to use\n */\n getContextMiddleware: (adapter: any) => any;\n\n /**\n * Apply middleware to app\n */\n applyMiddleware: (app: any, middleware: any) => void;\n}\n\n/**\n * Creates a standardized test suite for multipart/form-data handling in server adapters.\n *\n * Tests:\n * - File uploads are correctly parsed to Buffers\n * - JSON fields in FormData are parsed\n * - File size limits are enforced\n * - Error handling for malformed requests\n */\nexport function createMultipartTestSuite(config: MultipartTestSuiteConfig) {\n const {\n suiteName = 'Multipart FormData Tests',\n setupAdapter,\n startServer,\n registerRoute,\n getContextMiddleware,\n applyMiddleware,\n } = config;\n\n describe(suiteName, () => {\n let context: AdapterTestContext;\n let serverInfo: { baseUrl: string; cleanup: () => Promise<void> } | null = null;\n\n beforeEach(async () => {\n context = await createDefaultTestContext();\n });\n\n afterEach(async () => {\n if (serverInfo) {\n await serverInfo.cleanup();\n serverInfo = null;\n }\n });\n\n it('should parse file uploads as Buffers', async () => {\n const { adapter, app } = await setupAdapter(context);\n\n // Track received body\n let receivedBody: any;\n\n const testRoute: ServerRoute<any, any, any> = {\n method: 'POST',\n path: '/test/upload',\n responseType: 'json',\n handler: async (params: any) => {\n receivedBody = params;\n return { success: true, hasAudio: !!params.audio };\n },\n };\n\n applyMiddleware(app, getContextMiddleware(adapter));\n await registerRoute(adapter, app, testRoute, { prefix: '' });\n\n serverInfo = await startServer(app);\n\n // Create FormData with a file\n const formData = new FormData();\n const audioContent = new Uint8Array([0x52, 0x49, 0x46, 0x46]); // RIFF header bytes\n const audioBlob = new Blob([audioContent], { type: 'audio/wav' });\n formData.append('audio', audioBlob, 'test.wav');\n\n const response = await fetch(`${serverInfo.baseUrl}/test/upload`, {\n method: 'POST',\n body: formData,\n });\n\n expect(response.status).toBe(200);\n const result = await response.json();\n expect(result).toMatchObject({ success: true, hasAudio: true });\n\n // Verify the audio was parsed as a Buffer\n expect(receivedBody.audio).toBeDefined();\n expect(Buffer.isBuffer(receivedBody.audio)).toBe(true);\n expect(receivedBody.audio.length).toBe(4);\n });\n\n it('should parse JSON string fields in FormData', async () => {\n const { adapter, app } = await setupAdapter(context);\n\n let receivedBody: any;\n\n const testRoute: ServerRoute<any, any, any> = {\n method: 'POST',\n path: '/test/upload-with-options',\n responseType: 'json',\n handler: async (params: any) => {\n receivedBody = params;\n return { success: true };\n },\n };\n\n applyMiddleware(app, getContextMiddleware(adapter));\n await registerRoute(adapter, app, testRoute, { prefix: '' });\n\n serverInfo = await startServer(app);\n\n // Create FormData with file and JSON options\n const formData = new FormData();\n const audioBlob = new Blob([new Uint8Array([1, 2, 3, 4])], { type: 'audio/wav' });\n formData.append('audio', audioBlob, 'test.wav');\n formData.append('options', JSON.stringify({ language: 'en', format: 'mp3' }));\n\n const response = await fetch(`${serverInfo.baseUrl}/test/upload-with-options`, {\n method: 'POST',\n body: formData,\n });\n\n expect(response.status).toBe(200);\n\n // Verify options was parsed as object, not string\n expect(receivedBody.options).toBeDefined();\n expect(typeof receivedBody.options).toBe('object');\n expect(receivedBody.options.language).toBe('en');\n expect(receivedBody.options.format).toBe('mp3');\n });\n\n it('should handle plain string fields in FormData', async () => {\n const { adapter, app } = await setupAdapter(context);\n\n let receivedBody: any;\n\n const testRoute: ServerRoute<any, any, any> = {\n method: 'POST',\n path: '/test/upload-with-string',\n responseType: 'json',\n handler: async (params: any) => {\n receivedBody = params;\n return { success: true };\n },\n };\n\n applyMiddleware(app, getContextMiddleware(adapter));\n await registerRoute(adapter, app, testRoute, { prefix: '' });\n\n serverInfo = await startServer(app);\n\n // Create FormData with file and plain string field\n const formData = new FormData();\n const audioBlob = new Blob([new Uint8Array([1, 2, 3, 4])], { type: 'audio/wav' });\n formData.append('audio', audioBlob, 'test.wav');\n formData.append('name', 'test-recording');\n\n const response = await fetch(`${serverInfo.baseUrl}/test/upload-with-string`, {\n method: 'POST',\n body: formData,\n });\n\n expect(response.status).toBe(200);\n\n // Verify name remains a string (not parsed as JSON)\n expect(receivedBody.name).toBe('test-recording');\n });\n\n it('should reject files exceeding size limit', async () => {\n const maxSize = 100; // 100 bytes limit\n const { adapter, app } = await setupAdapter(context, {\n bodyLimitOptions: {\n maxSize,\n onError: (err: any) => ({ error: 'File too large' }),\n },\n });\n\n const testRoute: ServerRoute<any, any, any> = {\n method: 'POST',\n path: '/test/upload-limited',\n responseType: 'json',\n handler: async () => {\n return { success: true };\n },\n };\n\n applyMiddleware(app, getContextMiddleware(adapter));\n await registerRoute(adapter, app, testRoute, { prefix: '' });\n\n serverInfo = await startServer(app);\n\n // Create FormData with a file larger than the limit\n const formData = new FormData();\n const largeContent = new Uint8Array(200); // 200 bytes, exceeds 100 byte limit\n const largeBlob = new Blob([largeContent], { type: 'audio/wav' });\n formData.append('audio', largeBlob, 'large.wav');\n\n const response = await fetch(`${serverInfo.baseUrl}/test/upload-limited`, {\n method: 'POST',\n body: formData,\n });\n\n // Should return error status (413 or 500 depending on implementation)\n expect(response.status).toBeGreaterThanOrEqual(400);\n });\n\n it('should handle empty FormData gracefully', async () => {\n const { adapter, app } = await setupAdapter(context);\n\n let receivedBody: any;\n\n const testRoute: ServerRoute<any, any, any> = {\n method: 'POST',\n path: '/test/upload-empty',\n responseType: 'json',\n handler: async (params: any) => {\n receivedBody = params;\n return {\n success: true,\n // Filter out all system-injected params to get only body fields\n bodyKeys: Object.keys(params).filter(\n k =>\n ![\n 'mastra',\n 'requestContext',\n 'tools',\n 'taskStore',\n 'abortSignal',\n 'registeredTools',\n 'routePrefix',\n 'request',\n ].includes(k),\n ),\n };\n },\n };\n\n applyMiddleware(app, getContextMiddleware(adapter));\n await registerRoute(adapter, app, testRoute, { prefix: '' });\n\n serverInfo = await startServer(app);\n\n // Create empty FormData\n const formData = new FormData();\n\n const response = await fetch(`${serverInfo.baseUrl}/test/upload-empty`, {\n method: 'POST',\n body: formData,\n });\n\n expect(response.status).toBe(200);\n const result = await response.json();\n expect(result).toMatchObject({ success: true, bodyKeys: [] });\n });\n\n it('should handle multiple files', async () => {\n const { adapter, app } = await setupAdapter(context);\n\n let receivedBody: any;\n\n const testRoute: ServerRoute<any, any, any> = {\n method: 'POST',\n path: '/test/upload-multiple',\n responseType: 'json',\n handler: async (params: any) => {\n receivedBody = params;\n return {\n success: true,\n hasFile1: !!params.file1,\n hasFile2: !!params.file2,\n };\n },\n };\n\n applyMiddleware(app, getContextMiddleware(adapter));\n await registerRoute(adapter, app, testRoute, { prefix: '' });\n\n serverInfo = await startServer(app);\n\n // Create FormData with multiple files\n const formData = new FormData();\n const file1 = new Blob([new Uint8Array([1, 2, 3])], { type: 'audio/wav' });\n const file2 = new Blob([new Uint8Array([4, 5, 6])], { type: 'audio/wav' });\n formData.append('file1', file1, 'file1.wav');\n formData.append('file2', file2, 'file2.wav');\n\n const response = await fetch(`${serverInfo.baseUrl}/test/upload-multiple`, {\n method: 'POST',\n body: formData,\n });\n\n expect(response.status).toBe(200);\n const result = await response.json();\n expect(result).toMatchObject({ hasFile1: true, hasFile2: true });\n\n // Verify both files were parsed\n expect(Buffer.isBuffer(receivedBody.file1)).toBe(true);\n expect(Buffer.isBuffer(receivedBody.file2)).toBe(true);\n });\n\n it('should still handle JSON requests normally', async () => {\n const { adapter, app } = await setupAdapter(context);\n\n let receivedBody: any;\n\n const testRoute: ServerRoute<any, any, any> = {\n method: 'POST',\n path: '/test/json',\n responseType: 'json',\n handler: async (params: any) => {\n receivedBody = params;\n return { success: true, message: params.message };\n },\n };\n\n applyMiddleware(app, getContextMiddleware(adapter));\n await registerRoute(adapter, app, testRoute, { prefix: '' });\n\n serverInfo = await startServer(app);\n\n const response = await fetch(`${serverInfo.baseUrl}/test/json`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ message: 'Hello, World!' }),\n });\n\n expect(response.status).toBe(200);\n const result = await response.json();\n expect(result).toMatchObject({ success: true, message: 'Hello, World!' });\n });\n\n it('should ignore form fields named with special object keys', async () => {\n const { adapter, app } = await setupAdapter(context);\n\n const testRoute: ServerRoute<any, any, any> = {\n method: 'POST',\n path: '/test/upload-special-keys',\n responseType: 'json',\n handler: async (params: any) => {\n return {\n success: true,\n name: params.name ?? null,\n options: params.options ?? null,\n // Any of these becoming truthy means a special-key field leaked into the body\n inheritedIsAdmin: params.isAdmin ?? null,\n bodyKeys: Object.keys(params).filter(\n k =>\n ![\n 'mastra',\n 'requestContext',\n 'tools',\n 'taskStore',\n 'abortSignal',\n 'registeredTools',\n 'routePrefix',\n 'request',\n ].includes(k),\n ),\n };\n },\n };\n\n applyMiddleware(app, getContextMiddleware(adapter));\n await registerRoute(adapter, app, testRoute, { prefix: '' });\n\n serverInfo = await startServer(app);\n\n const formData = new FormData();\n // Field names that must never be written onto the parsed body object\n formData.append('__proto__', JSON.stringify({ isAdmin: true }));\n formData.append('constructor', JSON.stringify({ prototype: { isAdmin: true } }));\n const fileBlob = new Blob([new Uint8Array([1, 2, 3])], { type: 'application/octet-stream' });\n formData.append('prototype', fileBlob, 'payload.bin');\n // Legitimate fields alongside them\n formData.append('name', 'legit-recording');\n formData.append('options', JSON.stringify({ language: 'en' }));\n\n const response = await fetch(`${serverInfo.baseUrl}/test/upload-special-keys`, {\n method: 'POST',\n body: formData,\n });\n\n expect(response.status).toBe(200);\n const result: any = await response.json();\n expect(result.name).toBe('legit-recording');\n expect(result.options).toMatchObject({ language: 'en' });\n expect(result.inheritedIsAdmin).toBeNull();\n expect(result.bodyKeys).not.toContain('__proto__');\n expect(result.bodyKeys).not.toContain('constructor');\n expect(result.bodyKeys).not.toContain('prototype');\n // The process-wide Object.prototype must be untouched\n expect(({} as any).isAdmin).toBeUndefined();\n });\n });\n}\n","import { Mastra } from '@mastra/core/mastra';\nimport { describe, it, expect, beforeEach, vi } from 'vitest';\nimport type { AdapterTestContext } from './test-helpers';\nimport { createDefaultTestContext } from './test-helpers';\n\n/**\n * Configuration for HTTP logging test suite\n */\nexport interface HttpLoggingTestSuiteConfig<TApp> {\n /** Name for the test suite */\n suiteName?: string;\n\n /**\n * Setup adapter with given Mastra instance\n */\n setupAdapter: (app: TApp, mastra: Mastra) => { adapter: any; app: TApp } | Promise<{ adapter: any; app: TApp }>;\n\n /**\n * Create a new app instance\n */\n createApp: () => TApp;\n\n /**\n * Register a route handler for testing\n * Returns a function to register the route (called after init for some adapters)\n */\n addRoute: (\n app: TApp,\n method: 'GET' | 'POST' | 'PUT' | 'DELETE',\n path: string,\n handler: (req: any) => any | Promise<any>,\n ) => void | Promise<void>;\n\n /**\n * Execute an HTTP request against the app\n */\n executeRequest: (\n app: TApp,\n method: string,\n url: string,\n options?: { headers?: Record<string, string>; body?: string },\n ) => Promise<{ status: number }>;\n}\n\n/**\n * Creates a standardized test suite for HTTP logging across all server adapters.\n *\n * Tests:\n * - Disabled logging (no logs when apiReqLogs is false)\n * - Default logging (info level with basic fields)\n * - Custom log levels (debug, info, warn)\n * - Path exclusion (health checks, metrics)\n * - Query parameter inclusion\n * - Header inclusion\n * - Sensitive header redaction (default and custom)\n * - Different HTTP methods (GET, POST, PUT, DELETE)\n * - Error status codes (404, 500)\n */\nexport function createHttpLoggingTestSuite<TApp>(config: HttpLoggingTestSuiteConfig<TApp>) {\n const { suiteName = 'HTTP Logging', setupAdapter, createApp, addRoute, executeRequest } = config;\n\n describe(suiteName, () => {\n let app: TApp;\n let logSpy: ReturnType<typeof vi.spyOn>;\n\n beforeEach(() => {\n app = createApp();\n vi.clearAllMocks();\n });\n\n it('should not log when apiReqLogs is disabled', async () => {\n const mastra = new Mastra({});\n const { adapter } = await setupAdapter(app, mastra);\n\n logSpy = vi.spyOn(adapter.logger, 'info');\n\n await adapter.init();\n\n await addRoute(app, 'GET', '/test', () => ({ message: 'success' }));\n\n await executeRequest(app, 'GET', 'http://localhost/test');\n\n expect(logSpy).not.toHaveBeenCalled();\n });\n\n it('should log HTTP requests when enabled with default config', async () => {\n const mastra = new Mastra({\n server: {\n build: {\n apiReqLogs: true,\n },\n },\n });\n const { adapter } = await setupAdapter(app, mastra);\n\n logSpy = vi.spyOn(adapter.logger, 'info');\n\n await adapter.init();\n\n await addRoute(app, 'GET', '/test', () => ({ message: 'success' }));\n\n const response = await executeRequest(app, 'GET', 'http://localhost/test');\n\n expect(response.status).toBe(200);\n expect(logSpy).toHaveBeenCalledWith(\n expect.stringMatching(/GET \\/test 200 \\d+ms/),\n expect.objectContaining({\n method: 'GET',\n path: '/test',\n status: 200,\n duration: expect.stringMatching(/\\d+ms/),\n }),\n );\n });\n\n it('should use custom log level', async () => {\n const mastra = new Mastra({\n server: {\n build: {\n apiReqLogs: {\n enabled: true,\n level: 'debug',\n },\n },\n },\n });\n const { adapter } = await setupAdapter(app, mastra);\n\n const debugSpy = vi.spyOn(adapter.logger, 'debug');\n\n await adapter.init();\n\n await addRoute(app, 'GET', '/test', () => ({ message: 'success' }));\n\n await executeRequest(app, 'GET', 'http://localhost/test');\n\n expect(debugSpy).toHaveBeenCalledWith(expect.stringMatching(/GET \\/test 200 \\d+ms/), expect.any(Object));\n });\n\n it('should exclude paths from logging', async () => {\n const mastra = new Mastra({\n server: {\n build: {\n apiReqLogs: {\n enabled: true,\n excludePaths: ['/health', '/ready'],\n },\n },\n },\n });\n const { adapter } = await setupAdapter(app, mastra);\n\n logSpy = vi.spyOn(adapter.logger, 'info');\n\n await adapter.init();\n\n await addRoute(app, 'GET', '/health', () => ({ status: 'ok' }));\n await addRoute(app, 'GET', '/test', () => ({ message: 'success' }));\n\n await executeRequest(app, 'GET', 'http://localhost/health');\n await executeRequest(app, 'GET', 'http://localhost/test');\n\n expect(logSpy).toHaveBeenCalledTimes(1);\n expect(logSpy).toHaveBeenCalledWith(expect.stringMatching(/GET \\/test 200/), expect.any(Object));\n });\n\n it('should include query params when configured', async () => {\n const mastra = new Mastra({\n server: {\n build: {\n apiReqLogs: {\n enabled: true,\n includeQueryParams: true,\n },\n },\n },\n });\n const { adapter } = await setupAdapter(app, mastra);\n\n logSpy = vi.spyOn(adapter.logger, 'info');\n\n await adapter.init();\n\n await addRoute(app, 'GET', '/test', () => ({ message: 'success' }));\n\n await executeRequest(app, 'GET', 'http://localhost/test?foo=bar&baz=qux');\n\n expect(logSpy).toHaveBeenCalledWith(\n expect.any(String),\n expect.objectContaining({\n query: expect.objectContaining({\n foo: 'bar',\n baz: 'qux',\n }),\n }),\n );\n });\n\n it('should include headers when configured', async () => {\n const mastra = new Mastra({\n server: {\n build: {\n apiReqLogs: {\n enabled: true,\n includeHeaders: true,\n },\n },\n },\n });\n const { adapter } = await setupAdapter(app, mastra);\n\n logSpy = vi.spyOn(adapter.logger, 'info');\n\n await adapter.init();\n\n await addRoute(app, 'GET', '/test', () => ({ message: 'success' }));\n\n await executeRequest(app, 'GET', 'http://localhost/test', {\n headers: {\n 'x-custom-header': 'custom-value',\n 'user-agent': 'test-client',\n },\n });\n\n expect(logSpy).toHaveBeenCalledWith(\n expect.any(String),\n expect.objectContaining({\n headers: expect.objectContaining({\n 'x-custom-header': 'custom-value',\n 'user-agent': 'test-client',\n }),\n }),\n );\n });\n\n it('should redact sensitive headers by default', async () => {\n const mastra = new Mastra({\n server: {\n build: {\n apiReqLogs: {\n enabled: true,\n includeHeaders: true,\n },\n },\n },\n });\n const { adapter } = await setupAdapter(app, mastra);\n\n logSpy = vi.spyOn(adapter.logger, 'info');\n\n await adapter.init();\n\n await addRoute(app, 'GET', '/test', () => ({ message: 'success' }));\n\n await executeRequest(app, 'GET', 'http://localhost/test', {\n headers: {\n authorization: 'Bearer secret-token',\n cookie: 'session=secret-session',\n 'x-custom': 'not-sensitive',\n },\n });\n\n expect(logSpy).toHaveBeenCalledWith(\n expect.any(String),\n expect.objectContaining({\n headers: expect.objectContaining({\n authorization: '[REDACTED]',\n cookie: '[REDACTED]',\n 'x-custom': 'not-sensitive',\n }),\n }),\n );\n });\n\n it('should support custom redactHeaders', async () => {\n const mastra = new Mastra({\n server: {\n build: {\n apiReqLogs: {\n enabled: true,\n includeHeaders: true,\n redactHeaders: ['x-api-key', 'x-secret'],\n },\n },\n },\n });\n const { adapter } = await setupAdapter(app, mastra);\n\n logSpy = vi.spyOn(adapter.logger, 'info');\n\n await adapter.init();\n\n await addRoute(app, 'GET', '/test', () => ({ message: 'success' }));\n\n await executeRequest(app, 'GET', 'http://localhost/test', {\n headers: {\n 'x-api-key': 'secret-key',\n 'x-secret': 'secret-value',\n authorization: 'Bearer token',\n },\n });\n\n expect(logSpy).toHaveBeenCalledWith(\n expect.any(String),\n expect.objectContaining({\n headers: expect.objectContaining({\n 'x-api-key': '[REDACTED]',\n 'x-secret': '[REDACTED]',\n authorization: '[REDACTED]', // Defaults are always merged with custom redact list\n }),\n }),\n );\n });\n\n it('should log different HTTP methods', async () => {\n const mastra = new Mastra({\n server: {\n build: {\n apiReqLogs: true,\n },\n },\n });\n const { adapter } = await setupAdapter(app, mastra);\n\n logSpy = vi.spyOn(adapter.logger, 'info');\n\n await adapter.init();\n\n await addRoute(app, 'GET', '/test', () => ({ message: 'get' }));\n await addRoute(app, 'POST', '/test', () => ({ message: 'post' }));\n await addRoute(app, 'PUT', '/test', () => ({ message: 'put' }));\n await addRoute(app, 'DELETE', '/test', () => ({ message: 'delete' }));\n\n await executeRequest(app, 'GET', 'http://localhost/test');\n await executeRequest(app, 'POST', 'http://localhost/test', { body: '{}' });\n await executeRequest(app, 'PUT', 'http://localhost/test', { body: '{}' });\n await executeRequest(app, 'DELETE', 'http://localhost/test');\n\n expect(logSpy).toHaveBeenCalledTimes(4);\n expect(logSpy).toHaveBeenCalledWith(expect.stringMatching(/GET \\/test 200/), expect.any(Object));\n expect(logSpy).toHaveBeenCalledWith(expect.stringMatching(/POST \\/test 200/), expect.any(Object));\n expect(logSpy).toHaveBeenCalledWith(expect.stringMatching(/PUT \\/test 200/), expect.any(Object));\n expect(logSpy).toHaveBeenCalledWith(expect.stringMatching(/DELETE \\/test 200/), expect.any(Object));\n });\n\n it('should log error status codes', async () => {\n const mastra = new Mastra({\n server: {\n build: {\n apiReqLogs: true,\n },\n },\n });\n const { adapter } = await setupAdapter(app, mastra);\n\n logSpy = vi.spyOn(adapter.logger, 'info');\n\n await adapter.init();\n\n await addRoute(app, 'GET', '/not-found', () => ({ status: 404, body: { error: 'Not found' } }));\n await addRoute(app, 'GET', '/error', () => ({ status: 500, body: { error: 'Internal error' } }));\n\n await executeRequest(app, 'GET', 'http://localhost/not-found');\n await executeRequest(app, 'GET', 'http://localhost/error');\n\n expect(logSpy).toHaveBeenCalledWith(expect.stringMatching(/GET \\/not-found 404/), expect.any(Object));\n expect(logSpy).toHaveBeenCalledWith(expect.stringMatching(/GET \\/error 500/), expect.any(Object));\n });\n });\n}\n","import { Mastra } from '@mastra/core/mastra';\nimport type { BodyLimitOptions, ServerRoute } from '@mastra/server/server-adapter';\nimport { describe, it, expect } from 'vitest';\n\n/**\n * Configuration for the body-limit test suite\n */\nexport interface BodyLimitTestSuiteConfig<TApp> {\n /** Name for the test suite */\n suiteName?: string;\n\n /** Body size limit (in bytes) to configure the adapter with. Defaults to 100. */\n maxSize?: number;\n\n /** Create a new app instance */\n createApp: () => TApp;\n\n /**\n * Construct the adapter for the given app/Mastra instance with the provided\n * bodyLimitOptions, wiring up any context middleware the adapter needs.\n */\n setupAdapter: (\n app: TApp,\n mastra: Mastra,\n bodyLimitOptions?: BodyLimitOptions,\n ) => { adapter: any; app: TApp } | Promise<{ adapter: any; app: TApp }>;\n\n /** Register the given ServerRoute on the app through the adapter's registerRoute() */\n registerRoute: (adapter: any, app: TApp, route: ServerRoute<any, any, any>) => void | Promise<void>;\n\n /** Execute an HTTP request against the app and return its status code */\n executeRequest: (\n app: TApp,\n method: string,\n url: string,\n options?: { headers?: Record<string, string>; body?: string },\n ) => Promise<{ status: number }>;\n\n /** Execute a request whose transport does not add Content-Length. */\n executeRequestWithoutContentLength?: (\n app: TApp,\n method: string,\n url: string,\n options?: { headers?: Record<string, string>; body?: string },\n ) => Promise<{ status: number }>;\n\n /** Optional teardown for the app instance (e.g. closing a listening server) */\n cleanupApp?: (app: TApp) => void | Promise<void>;\n}\n\n/**\n * Creates a standardized body-limit test suite for server adapters.\n *\n * Exercises the adapter's registerRoute() body-limit gate (bodyLimitOptions.maxSize)\n * for both POST and DELETE. DELETE is included alongside the long-established POST\n * behavior as regression coverage: DELETE requests previously bypassed the body-limit\n * check entirely, even though the adapters' getParams() reads and JSON-parses the\n * request body for DELETE the same way it does for POST/PUT/PATCH.\n */\nexport function createBodyLimitTestSuite<TApp>(config: BodyLimitTestSuiteConfig<TApp>) {\n const {\n suiteName = 'Body Size Limit',\n maxSize = 100,\n createApp,\n setupAdapter,\n registerRoute,\n executeRequest,\n executeRequestWithoutContentLength,\n cleanupApp,\n } = config;\n\n describe(suiteName, () => {\n const oversizedPayload = JSON.stringify({ padding: 'x'.repeat(maxSize * 4) });\n\n it('enforces a route-specific limit without global body limit options', async () => {\n const mastra = new Mastra({});\n const app = createApp();\n const { adapter, app: wiredApp } = await setupAdapter(app, mastra);\n let handlerCalled = false;\n\n const testRoute: ServerRoute<any, any, any> = {\n method: 'POST',\n path: '/test/route-body-limit',\n responseType: 'json',\n maxBodySize: maxSize,\n handler: async ({ body }) => {\n handlerCalled = true;\n return { receivedBody: body };\n },\n };\n\n await registerRoute(adapter, wiredApp, testRoute);\n\n const response = await executeRequest(wiredApp, 'POST', 'http://localhost/test/route-body-limit', {\n headers: { 'Content-Type': 'application/json' },\n body: oversizedPayload,\n });\n\n expect(response.status).toBe(413);\n expect(handlerCalled).toBe(false);\n\n await cleanupApp?.(wiredApp);\n });\n\n if (executeRequestWithoutContentLength) {\n it('rejects an oversized route body without Content-Length before handler execution', async () => {\n const mastra = new Mastra({});\n const app = createApp();\n const { adapter, app: wiredApp } = await setupAdapter(app, mastra);\n let handlerCalled = false;\n\n const testRoute: ServerRoute<any, any, any> = {\n method: 'POST',\n path: '/test/route-body-limit-no-content-length',\n responseType: 'json',\n maxBodySize: maxSize,\n handler: async ({ body }) => {\n handlerCalled = true;\n return { receivedBody: body };\n },\n };\n\n await registerRoute(adapter, wiredApp, testRoute);\n\n const response = await executeRequestWithoutContentLength(\n wiredApp,\n 'POST',\n 'http://localhost/test/route-body-limit-no-content-length',\n {\n headers: { 'Content-Type': 'application/json' },\n body: oversizedPayload,\n },\n );\n\n expect(response.status).toBe(413);\n expect(handlerCalled).toBe(false);\n\n await cleanupApp?.(wiredApp);\n });\n }\n\n it.each(['POST', 'DELETE'] as const)('rejects an oversized %s body with 413', async method => {\n const mastra = new Mastra({});\n const app = createApp();\n const { adapter, app: wiredApp } = await setupAdapter(app, mastra, {\n maxSize,\n onError: () => ({ error: 'Request body too large' }),\n });\n\n const testRoute: ServerRoute<any, any, any> = {\n method,\n path: '/test/body-limit',\n responseType: 'json',\n handler: async ({ body }) => ({ receivedBody: body }),\n };\n\n await registerRoute(adapter, wiredApp, testRoute);\n\n const response = await executeRequest(wiredApp, method, 'http://localhost/test/body-limit', {\n headers: { 'Content-Type': 'application/json' },\n body: oversizedPayload,\n });\n\n expect(response.status).toBe(413);\n\n await cleanupApp?.(wiredApp);\n });\n });\n}\n"],"mappings":"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"}