@sparkleideas/testing 3.0.0-alpha.10

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.
Files changed (42) hide show
  1. package/README.md +547 -0
  2. package/__tests__/framework.test.ts +21 -0
  3. package/package.json +61 -0
  4. package/src/fixtures/agent-fixtures.ts +793 -0
  5. package/src/fixtures/agents.ts +212 -0
  6. package/src/fixtures/configurations.ts +491 -0
  7. package/src/fixtures/index.ts +21 -0
  8. package/src/fixtures/mcp-fixtures.ts +1030 -0
  9. package/src/fixtures/memory-entries.ts +328 -0
  10. package/src/fixtures/memory-fixtures.ts +750 -0
  11. package/src/fixtures/swarm-fixtures.ts +837 -0
  12. package/src/fixtures/tasks.ts +309 -0
  13. package/src/helpers/assertion-helpers.ts +616 -0
  14. package/src/helpers/assertions.ts +286 -0
  15. package/src/helpers/create-mock.ts +200 -0
  16. package/src/helpers/index.ts +182 -0
  17. package/src/helpers/mock-factory.ts +711 -0
  18. package/src/helpers/setup-teardown.ts +678 -0
  19. package/src/helpers/swarm-instance.ts +326 -0
  20. package/src/helpers/test-application.ts +310 -0
  21. package/src/helpers/test-utils.ts +670 -0
  22. package/src/index.ts +232 -0
  23. package/src/mocks/index.ts +29 -0
  24. package/src/mocks/mock-mcp-client.ts +723 -0
  25. package/src/mocks/mock-services.ts +793 -0
  26. package/src/regression/api-contract.ts +473 -0
  27. package/src/regression/index.ts +46 -0
  28. package/src/regression/integration-regression.ts +416 -0
  29. package/src/regression/performance-baseline.ts +356 -0
  30. package/src/regression/regression-runner.ts +339 -0
  31. package/src/regression/security-regression.ts +331 -0
  32. package/src/setup.ts +127 -0
  33. package/src/v2-compat/api-compat.test.ts +590 -0
  34. package/src/v2-compat/cli-compat.test.ts +484 -0
  35. package/src/v2-compat/compatibility-validator.ts +1072 -0
  36. package/src/v2-compat/hooks-compat.test.ts +602 -0
  37. package/src/v2-compat/index.ts +58 -0
  38. package/src/v2-compat/mcp-compat.test.ts +557 -0
  39. package/src/v2-compat/report-generator.ts +441 -0
  40. package/tmp.json +0 -0
  41. package/tsconfig.json +20 -0
  42. package/vitest.config.ts +12 -0
@@ -0,0 +1,1030 @@
1
+ /**
2
+ * @sparkleideas/testing - MCP Fixtures
3
+ *
4
+ * Comprehensive mock MCP tools, contexts, and server configurations for testing.
5
+ * Supports all MCP protocol operations and Claude-Flow tool integrations.
6
+ *
7
+ * Based on ADR-005 (MCP-first API design) and V3 specifications.
8
+ */
9
+ import { vi, type Mock } from 'vitest';
10
+
11
+ /**
12
+ * MCP transport types
13
+ */
14
+ export type MCPTransportType = 'stdio' | 'http' | 'websocket';
15
+
16
+ /**
17
+ * MCP content types
18
+ */
19
+ export type MCPContentType = 'text' | 'image' | 'resource';
20
+
21
+ /**
22
+ * MCP input schema type (JSON Schema subset)
23
+ */
24
+ export interface MCPInputSchema {
25
+ type: 'object';
26
+ properties: Record<string, MCPPropertySchema>;
27
+ required?: string[];
28
+ additionalProperties?: boolean;
29
+ }
30
+
31
+ /**
32
+ * MCP property schema
33
+ */
34
+ export interface MCPPropertySchema {
35
+ type: 'string' | 'number' | 'boolean' | 'array' | 'object';
36
+ description?: string;
37
+ enum?: unknown[];
38
+ default?: unknown;
39
+ items?: MCPPropertySchema;
40
+ properties?: Record<string, MCPPropertySchema>;
41
+ required?: string[];
42
+ }
43
+
44
+ /**
45
+ * MCP tool definition
46
+ */
47
+ export interface MCPTool {
48
+ name: string;
49
+ description: string;
50
+ inputSchema: MCPInputSchema;
51
+ handler?: (params: Record<string, unknown>) => Promise<MCPToolResult>;
52
+ }
53
+
54
+ /**
55
+ * MCP tool result
56
+ */
57
+ export interface MCPToolResult {
58
+ content: MCPContent[];
59
+ isError?: boolean;
60
+ }
61
+
62
+ /**
63
+ * MCP content (text, image, or resource)
64
+ */
65
+ export type MCPContent = MCPTextContent | MCPImageContent | MCPResourceContent;
66
+
67
+ /**
68
+ * MCP text content
69
+ */
70
+ export interface MCPTextContent {
71
+ type: 'text';
72
+ text: string;
73
+ }
74
+
75
+ /**
76
+ * MCP image content
77
+ */
78
+ export interface MCPImageContent {
79
+ type: 'image';
80
+ data: string;
81
+ mimeType: string;
82
+ }
83
+
84
+ /**
85
+ * MCP resource content
86
+ */
87
+ export interface MCPResourceContent {
88
+ type: 'resource';
89
+ resource: {
90
+ uri: string;
91
+ mimeType?: string;
92
+ text?: string;
93
+ blob?: string;
94
+ };
95
+ }
96
+
97
+ /**
98
+ * MCP server configuration
99
+ */
100
+ export interface MCPServerConfig {
101
+ name: string;
102
+ version: string;
103
+ transport: MCPTransportConfig;
104
+ tools?: MCPTool[];
105
+ resources?: MCPResource[];
106
+ prompts?: MCPPrompt[];
107
+ capabilities?: MCPCapabilities;
108
+ }
109
+
110
+ /**
111
+ * MCP transport configuration
112
+ */
113
+ export interface MCPTransportConfig {
114
+ type: MCPTransportType;
115
+ port?: number;
116
+ host?: string;
117
+ path?: string;
118
+ timeout?: number;
119
+ }
120
+
121
+ /**
122
+ * MCP resource definition
123
+ */
124
+ export interface MCPResource {
125
+ uri: string;
126
+ name: string;
127
+ description?: string;
128
+ mimeType?: string;
129
+ }
130
+
131
+ /**
132
+ * MCP prompt definition
133
+ */
134
+ export interface MCPPrompt {
135
+ name: string;
136
+ description?: string;
137
+ arguments?: MCPPromptArgument[];
138
+ }
139
+
140
+ /**
141
+ * MCP prompt argument
142
+ */
143
+ export interface MCPPromptArgument {
144
+ name: string;
145
+ description?: string;
146
+ required?: boolean;
147
+ }
148
+
149
+ /**
150
+ * MCP capabilities
151
+ */
152
+ export interface MCPCapabilities {
153
+ tools?: boolean;
154
+ resources?: boolean;
155
+ prompts?: boolean;
156
+ logging?: boolean;
157
+ experimental?: Record<string, boolean>;
158
+ }
159
+
160
+ /**
161
+ * MCP request base
162
+ */
163
+ export interface MCPRequestBase {
164
+ jsonrpc: '2.0';
165
+ id: string | number;
166
+ method: string;
167
+ params?: Record<string, unknown>;
168
+ }
169
+
170
+ /**
171
+ * MCP response base
172
+ */
173
+ export interface MCPResponseBase<T = unknown> {
174
+ jsonrpc: '2.0';
175
+ id: string | number;
176
+ result?: T;
177
+ error?: MCPError;
178
+ }
179
+
180
+ /**
181
+ * MCP error
182
+ */
183
+ export interface MCPError {
184
+ code: number;
185
+ message: string;
186
+ data?: unknown;
187
+ }
188
+
189
+ /**
190
+ * MCP server status
191
+ */
192
+ export interface MCPServerStatus {
193
+ running: boolean;
194
+ transport: MCPTransportType;
195
+ connectedClients: number;
196
+ toolsRegistered: number;
197
+ resourcesRegistered: number;
198
+ promptsRegistered: number;
199
+ requestsHandled: number;
200
+ errorsCount: number;
201
+ uptime: number;
202
+ }
203
+
204
+ /**
205
+ * MCP session context
206
+ */
207
+ export interface MCPSessionContext {
208
+ sessionId: string;
209
+ clientInfo: {
210
+ name: string;
211
+ version: string;
212
+ };
213
+ capabilities: MCPCapabilities;
214
+ startedAt: Date;
215
+ lastActivity: Date;
216
+ requestCount: number;
217
+ }
218
+
219
+ /**
220
+ * Pre-defined MCP tools for Claude-Flow
221
+ */
222
+ export const mcpTools: Record<string, MCPTool> = {
223
+ // Swarm management tools
224
+ swarmInit: {
225
+ name: 'swarm_init',
226
+ description: 'Initialize a new swarm with specified topology and configuration',
227
+ inputSchema: {
228
+ type: 'object',
229
+ properties: {
230
+ topology: {
231
+ type: 'string',
232
+ description: 'Swarm topology (hierarchical, mesh, adaptive, hierarchical-mesh)',
233
+ enum: ['hierarchical', 'mesh', 'ring', 'star', 'adaptive', 'hierarchical-mesh'],
234
+ },
235
+ maxAgents: {
236
+ type: 'number',
237
+ description: 'Maximum number of agents in the swarm',
238
+ default: 15,
239
+ },
240
+ consensusProtocol: {
241
+ type: 'string',
242
+ description: 'Consensus protocol to use',
243
+ enum: ['raft', 'pbft', 'gossip', 'byzantine'],
244
+ },
245
+ },
246
+ required: ['topology'],
247
+ },
248
+ },
249
+
250
+ agentSpawn: {
251
+ name: 'agent_spawn',
252
+ description: 'Spawn a new agent with specified type and configuration',
253
+ inputSchema: {
254
+ type: 'object',
255
+ properties: {
256
+ type: {
257
+ type: 'string',
258
+ description: 'Agent type (queen-coordinator, coder, tester, etc.)',
259
+ },
260
+ name: {
261
+ type: 'string',
262
+ description: 'Agent name',
263
+ },
264
+ capabilities: {
265
+ type: 'array',
266
+ description: 'Agent capabilities',
267
+ items: { type: 'string' },
268
+ },
269
+ priority: {
270
+ type: 'number',
271
+ description: 'Agent priority (0-100)',
272
+ default: 50,
273
+ },
274
+ },
275
+ required: ['type'],
276
+ },
277
+ },
278
+
279
+ taskOrchestrate: {
280
+ name: 'task_orchestrate',
281
+ description: 'Orchestrate a task across multiple agents',
282
+ inputSchema: {
283
+ type: 'object',
284
+ properties: {
285
+ taskName: {
286
+ type: 'string',
287
+ description: 'Name of the task',
288
+ },
289
+ taskType: {
290
+ type: 'string',
291
+ description: 'Type of task (security, coding, testing, review)',
292
+ },
293
+ payload: {
294
+ type: 'object',
295
+ description: 'Task payload',
296
+ },
297
+ agents: {
298
+ type: 'array',
299
+ description: 'List of agent IDs to coordinate',
300
+ items: { type: 'string' },
301
+ },
302
+ parallel: {
303
+ type: 'boolean',
304
+ description: 'Execute tasks in parallel',
305
+ default: true,
306
+ },
307
+ },
308
+ required: ['taskName', 'taskType'],
309
+ },
310
+ },
311
+
312
+ // Memory tools
313
+ memoryStore: {
314
+ name: 'memory_store',
315
+ description: 'Store a value in memory with optional embedding',
316
+ inputSchema: {
317
+ type: 'object',
318
+ properties: {
319
+ key: {
320
+ type: 'string',
321
+ description: 'Memory key',
322
+ },
323
+ value: {
324
+ type: 'object',
325
+ description: 'Value to store',
326
+ },
327
+ type: {
328
+ type: 'string',
329
+ description: 'Memory type',
330
+ enum: ['short-term', 'long-term', 'semantic', 'episodic'],
331
+ },
332
+ ttl: {
333
+ type: 'number',
334
+ description: 'Time-to-live in milliseconds',
335
+ },
336
+ generateEmbedding: {
337
+ type: 'boolean',
338
+ description: 'Generate vector embedding for semantic search',
339
+ default: false,
340
+ },
341
+ },
342
+ required: ['key', 'value'],
343
+ },
344
+ },
345
+
346
+ memorySearch: {
347
+ name: 'memory_search',
348
+ description: 'Search memory using semantic vector search',
349
+ inputSchema: {
350
+ type: 'object',
351
+ properties: {
352
+ query: {
353
+ type: 'string',
354
+ description: 'Search query',
355
+ },
356
+ topK: {
357
+ type: 'number',
358
+ description: 'Number of results to return',
359
+ default: 10,
360
+ },
361
+ threshold: {
362
+ type: 'number',
363
+ description: 'Minimum similarity threshold (0-1)',
364
+ default: 0.7,
365
+ },
366
+ filters: {
367
+ type: 'object',
368
+ description: 'Additional filters',
369
+ },
370
+ },
371
+ required: ['query'],
372
+ },
373
+ },
374
+
375
+ // Status tools
376
+ swarmStatus: {
377
+ name: 'swarm_status',
378
+ description: 'Get current swarm status and metrics',
379
+ inputSchema: {
380
+ type: 'object',
381
+ properties: {
382
+ includeMetrics: {
383
+ type: 'boolean',
384
+ description: 'Include detailed metrics',
385
+ default: true,
386
+ },
387
+ includeAgents: {
388
+ type: 'boolean',
389
+ description: 'Include agent details',
390
+ default: false,
391
+ },
392
+ },
393
+ },
394
+ },
395
+
396
+ agentList: {
397
+ name: 'agent_list',
398
+ description: 'List all agents in the swarm',
399
+ inputSchema: {
400
+ type: 'object',
401
+ properties: {
402
+ status: {
403
+ type: 'string',
404
+ description: 'Filter by agent status',
405
+ enum: ['idle', 'busy', 'terminated', 'error', 'all'],
406
+ },
407
+ type: {
408
+ type: 'string',
409
+ description: 'Filter by agent type',
410
+ },
411
+ },
412
+ },
413
+ },
414
+
415
+ agentMetrics: {
416
+ name: 'agent_metrics',
417
+ description: 'Get metrics for a specific agent',
418
+ inputSchema: {
419
+ type: 'object',
420
+ properties: {
421
+ agentId: {
422
+ type: 'string',
423
+ description: 'Agent ID',
424
+ },
425
+ },
426
+ required: ['agentId'],
427
+ },
428
+ },
429
+
430
+ // Neural/Learning tools
431
+ neuralStatus: {
432
+ name: 'neural_status',
433
+ description: 'Get neural learning system status',
434
+ inputSchema: {
435
+ type: 'object',
436
+ properties: {
437
+ includePatterns: {
438
+ type: 'boolean',
439
+ description: 'Include learned patterns summary',
440
+ default: false,
441
+ },
442
+ },
443
+ },
444
+ },
445
+
446
+ neuralTrain: {
447
+ name: 'neural_train',
448
+ description: 'Trigger neural training with current data',
449
+ inputSchema: {
450
+ type: 'object',
451
+ properties: {
452
+ algorithm: {
453
+ type: 'string',
454
+ description: 'Training algorithm',
455
+ enum: ['ppo', 'dqn', 'a2c', 'sarsa', 'q-learning'],
456
+ },
457
+ epochs: {
458
+ type: 'number',
459
+ description: 'Number of training epochs',
460
+ default: 10,
461
+ },
462
+ },
463
+ },
464
+ },
465
+
466
+ // GitHub integration tools
467
+ githubSwarm: {
468
+ name: 'github_swarm',
469
+ description: 'Initialize GitHub integration for a repository',
470
+ inputSchema: {
471
+ type: 'object',
472
+ properties: {
473
+ repo: {
474
+ type: 'string',
475
+ description: 'Repository in owner/repo format',
476
+ },
477
+ features: {
478
+ type: 'array',
479
+ description: 'Features to enable',
480
+ items: { type: 'string' },
481
+ default: ['issues', 'prs', 'reviews'],
482
+ },
483
+ },
484
+ required: ['repo'],
485
+ },
486
+ },
487
+
488
+ codeReview: {
489
+ name: 'code_review',
490
+ description: 'Request code review from swarm agents',
491
+ inputSchema: {
492
+ type: 'object',
493
+ properties: {
494
+ prNumber: {
495
+ type: 'number',
496
+ description: 'Pull request number',
497
+ },
498
+ repo: {
499
+ type: 'string',
500
+ description: 'Repository in owner/repo format',
501
+ },
502
+ focus: {
503
+ type: 'array',
504
+ description: 'Review focus areas',
505
+ items: { type: 'string' },
506
+ default: ['security', 'performance', 'style'],
507
+ },
508
+ },
509
+ required: ['prNumber', 'repo'],
510
+ },
511
+ },
512
+ };
513
+
514
+ /**
515
+ * Pre-defined MCP resources
516
+ */
517
+ export const mcpResources: Record<string, MCPResource> = {
518
+ swarmConfig: {
519
+ uri: 'claude-flow://config/swarm',
520
+ name: 'Swarm Configuration',
521
+ description: 'Current swarm configuration',
522
+ mimeType: 'application/json',
523
+ },
524
+
525
+ agentRegistry: {
526
+ uri: 'claude-flow://agents/registry',
527
+ name: 'Agent Registry',
528
+ description: 'Registry of all available agent types',
529
+ mimeType: 'application/json',
530
+ },
531
+
532
+ memoryStats: {
533
+ uri: 'claude-flow://memory/stats',
534
+ name: 'Memory Statistics',
535
+ description: 'Memory system statistics and metrics',
536
+ mimeType: 'application/json',
537
+ },
538
+
539
+ learningPatterns: {
540
+ uri: 'claude-flow://neural/patterns',
541
+ name: 'Learning Patterns',
542
+ description: 'Learned patterns from ReasoningBank',
543
+ mimeType: 'application/json',
544
+ },
545
+ };
546
+
547
+ /**
548
+ * Pre-defined MCP prompts
549
+ */
550
+ export const mcpPrompts: Record<string, MCPPrompt> = {
551
+ codeAnalysis: {
552
+ name: 'analyze_code',
553
+ description: 'Analyze code for security, performance, and style issues',
554
+ arguments: [
555
+ { name: 'language', description: 'Programming language', required: true },
556
+ { name: 'focus', description: 'Analysis focus area', required: false },
557
+ ],
558
+ },
559
+
560
+ taskPlanning: {
561
+ name: 'plan_task',
562
+ description: 'Generate a task execution plan',
563
+ arguments: [
564
+ { name: 'objective', description: 'Task objective', required: true },
565
+ { name: 'constraints', description: 'Task constraints', required: false },
566
+ ],
567
+ },
568
+
569
+ securityReview: {
570
+ name: 'security_review',
571
+ description: 'Perform security review on code or configuration',
572
+ arguments: [
573
+ { name: 'target', description: 'Review target (file, directory, config)', required: true },
574
+ { name: 'severity', description: 'Minimum severity level', required: false },
575
+ ],
576
+ },
577
+ };
578
+
579
+ /**
580
+ * Pre-defined MCP server configurations
581
+ */
582
+ export const mcpServerConfigs: Record<string, MCPServerConfig> = {
583
+ development: {
584
+ name: 'claude-flow-dev',
585
+ version: '3.0.0-alpha',
586
+ transport: {
587
+ type: 'http',
588
+ port: 3000,
589
+ host: 'localhost',
590
+ timeout: 30000,
591
+ },
592
+ tools: Object.values(mcpTools),
593
+ resources: Object.values(mcpResources),
594
+ prompts: Object.values(mcpPrompts),
595
+ capabilities: {
596
+ tools: true,
597
+ resources: true,
598
+ prompts: true,
599
+ logging: true,
600
+ experimental: { streaming: true },
601
+ },
602
+ },
603
+
604
+ production: {
605
+ name: 'claude-flow',
606
+ version: '3.0.0',
607
+ transport: {
608
+ type: 'http',
609
+ port: 443,
610
+ host: '0.0.0.0',
611
+ timeout: 15000,
612
+ },
613
+ capabilities: {
614
+ tools: true,
615
+ resources: true,
616
+ prompts: true,
617
+ logging: false,
618
+ },
619
+ },
620
+
621
+ stdio: {
622
+ name: 'claude-flow-stdio',
623
+ version: '3.0.0-alpha',
624
+ transport: {
625
+ type: 'stdio',
626
+ timeout: 60000,
627
+ },
628
+ capabilities: {
629
+ tools: true,
630
+ resources: true,
631
+ prompts: true,
632
+ logging: true,
633
+ },
634
+ },
635
+
636
+ websocket: {
637
+ name: 'claude-flow-ws',
638
+ version: '3.0.0-alpha',
639
+ transport: {
640
+ type: 'websocket',
641
+ port: 8080,
642
+ host: 'localhost',
643
+ path: '/mcp',
644
+ timeout: 30000,
645
+ },
646
+ capabilities: {
647
+ tools: true,
648
+ resources: true,
649
+ prompts: true,
650
+ logging: true,
651
+ experimental: { streaming: true, multiplexing: true },
652
+ },
653
+ },
654
+ };
655
+
656
+ /**
657
+ * Pre-defined MCP tool results
658
+ */
659
+ export const mcpToolResults: Record<string, MCPToolResult> = {
660
+ success: {
661
+ content: [
662
+ {
663
+ type: 'text',
664
+ text: 'Operation completed successfully',
665
+ },
666
+ ],
667
+ },
668
+
669
+ swarmInitialized: {
670
+ content: [
671
+ {
672
+ type: 'text',
673
+ text: JSON.stringify({
674
+ swarmId: 'swarm-001',
675
+ topology: 'hierarchical-mesh',
676
+ status: 'active',
677
+ agentCount: 15,
678
+ }),
679
+ },
680
+ ],
681
+ },
682
+
683
+ agentSpawned: {
684
+ content: [
685
+ {
686
+ type: 'text',
687
+ text: JSON.stringify({
688
+ agentId: 'agent-coder-001',
689
+ type: 'coder',
690
+ status: 'idle',
691
+ capabilities: ['coding', 'implementation', 'debugging'],
692
+ }),
693
+ },
694
+ ],
695
+ },
696
+
697
+ memorySearchResults: {
698
+ content: [
699
+ {
700
+ type: 'text',
701
+ text: JSON.stringify({
702
+ results: [
703
+ { key: 'pattern-001', score: 0.95 },
704
+ { key: 'pattern-002', score: 0.88 },
705
+ ],
706
+ totalCount: 2,
707
+ latencyMs: 15,
708
+ }),
709
+ },
710
+ ],
711
+ },
712
+
713
+ error: {
714
+ content: [
715
+ {
716
+ type: 'text',
717
+ text: 'Operation failed: Invalid parameters',
718
+ },
719
+ ],
720
+ isError: true,
721
+ },
722
+ };
723
+
724
+ /**
725
+ * Pre-defined MCP errors
726
+ */
727
+ export const mcpErrors: Record<string, MCPError> = {
728
+ parseError: {
729
+ code: -32700,
730
+ message: 'Parse error',
731
+ data: { details: 'Invalid JSON received' },
732
+ },
733
+
734
+ invalidRequest: {
735
+ code: -32600,
736
+ message: 'Invalid request',
737
+ data: { details: 'Missing required field' },
738
+ },
739
+
740
+ methodNotFound: {
741
+ code: -32601,
742
+ message: 'Method not found',
743
+ data: { method: 'unknown_method' },
744
+ },
745
+
746
+ invalidParams: {
747
+ code: -32602,
748
+ message: 'Invalid params',
749
+ data: { param: 'topology', expected: 'string' },
750
+ },
751
+
752
+ internalError: {
753
+ code: -32603,
754
+ message: 'Internal error',
755
+ data: { details: 'Unexpected server error' },
756
+ },
757
+
758
+ toolNotFound: {
759
+ code: -32001,
760
+ message: 'Tool not found',
761
+ data: { tool: 'unknown_tool' },
762
+ },
763
+
764
+ resourceNotFound: {
765
+ code: -32002,
766
+ message: 'Resource not found',
767
+ data: { uri: 'unknown://resource' },
768
+ },
769
+ };
770
+
771
+ /**
772
+ * Pre-defined session contexts
773
+ */
774
+ export const mcpSessionContexts: Record<string, MCPSessionContext> = {
775
+ active: {
776
+ sessionId: 'session-001',
777
+ clientInfo: {
778
+ name: 'claude-code',
779
+ version: '1.0.0',
780
+ },
781
+ capabilities: {
782
+ tools: true,
783
+ resources: true,
784
+ prompts: true,
785
+ },
786
+ startedAt: new Date('2024-01-15T10:00:00Z'),
787
+ lastActivity: new Date(),
788
+ requestCount: 42,
789
+ },
790
+
791
+ new: {
792
+ sessionId: 'session-002',
793
+ clientInfo: {
794
+ name: 'test-client',
795
+ version: '0.1.0',
796
+ },
797
+ capabilities: {
798
+ tools: true,
799
+ },
800
+ startedAt: new Date(),
801
+ lastActivity: new Date(),
802
+ requestCount: 0,
803
+ },
804
+
805
+ expired: {
806
+ sessionId: 'session-003',
807
+ clientInfo: {
808
+ name: 'old-client',
809
+ version: '0.0.1',
810
+ },
811
+ capabilities: {},
812
+ startedAt: new Date('2024-01-01T00:00:00Z'),
813
+ lastActivity: new Date('2024-01-01T01:00:00Z'),
814
+ requestCount: 5,
815
+ },
816
+ };
817
+
818
+ /**
819
+ * Factory function to create MCP tool
820
+ */
821
+ export function createMCPTool(
822
+ base: keyof typeof mcpTools,
823
+ overrides?: Partial<MCPTool>
824
+ ): MCPTool {
825
+ return {
826
+ ...mcpTools[base],
827
+ ...overrides,
828
+ };
829
+ }
830
+
831
+ /**
832
+ * Factory function to create MCP server config
833
+ */
834
+ export function createMCPServerConfig(
835
+ base: keyof typeof mcpServerConfigs = 'development',
836
+ overrides?: Partial<MCPServerConfig>
837
+ ): MCPServerConfig {
838
+ return {
839
+ ...mcpServerConfigs[base],
840
+ ...overrides,
841
+ };
842
+ }
843
+
844
+ /**
845
+ * Factory function to create MCP request
846
+ */
847
+ export function createMCPRequest(
848
+ method: string,
849
+ params?: Record<string, unknown>,
850
+ overrides?: Partial<MCPRequestBase>
851
+ ): MCPRequestBase {
852
+ return {
853
+ jsonrpc: '2.0',
854
+ id: `req-${Date.now()}`,
855
+ method,
856
+ params,
857
+ ...overrides,
858
+ };
859
+ }
860
+
861
+ /**
862
+ * Factory function to create MCP response
863
+ */
864
+ export function createMCPResponse<T>(
865
+ id: string | number,
866
+ result?: T,
867
+ error?: MCPError
868
+ ): MCPResponseBase<T> {
869
+ return {
870
+ jsonrpc: '2.0',
871
+ id,
872
+ result,
873
+ error,
874
+ };
875
+ }
876
+
877
+ /**
878
+ * Factory function to create MCP tool result
879
+ */
880
+ export function createMCPToolResult(
881
+ text: string,
882
+ isError: boolean = false
883
+ ): MCPToolResult {
884
+ return {
885
+ content: [{ type: 'text', text }],
886
+ isError,
887
+ };
888
+ }
889
+
890
+ /**
891
+ * Factory function to create session context
892
+ */
893
+ export function createMCPSessionContext(
894
+ base: keyof typeof mcpSessionContexts = 'active',
895
+ overrides?: Partial<MCPSessionContext>
896
+ ): MCPSessionContext {
897
+ return {
898
+ ...mcpSessionContexts[base],
899
+ ...overrides,
900
+ sessionId: overrides?.sessionId ?? `session-${Date.now()}`,
901
+ startedAt: overrides?.startedAt ?? new Date(),
902
+ lastActivity: overrides?.lastActivity ?? new Date(),
903
+ };
904
+ }
905
+
906
+ /**
907
+ * Invalid MCP configurations for error testing
908
+ */
909
+ export const invalidMCPConfigs = {
910
+ emptyName: {
911
+ ...mcpServerConfigs.development,
912
+ name: '',
913
+ },
914
+
915
+ invalidPort: {
916
+ ...mcpServerConfigs.development,
917
+ transport: {
918
+ type: 'http' as MCPTransportType,
919
+ port: -1,
920
+ host: 'localhost',
921
+ },
922
+ },
923
+
924
+ missingTransport: {
925
+ name: 'invalid-server',
926
+ version: '1.0.0',
927
+ transport: undefined as unknown as MCPTransportConfig,
928
+ },
929
+ };
930
+
931
+ /**
932
+ * Mock MCP client interface
933
+ */
934
+ export interface MockMCPClient {
935
+ connect: Mock<() => Promise<void>>;
936
+ disconnect: Mock<() => Promise<void>>;
937
+ callTool: Mock<(name: string, params: Record<string, unknown>) => Promise<MCPToolResult>>;
938
+ listTools: Mock<() => Promise<MCPTool[]>>;
939
+ readResource: Mock<(uri: string) => Promise<MCPResourceContent>>;
940
+ listResources: Mock<() => Promise<MCPResource[]>>;
941
+ getPrompt: Mock<(name: string, args: Record<string, string>) => Promise<string>>;
942
+ listPrompts: Mock<() => Promise<MCPPrompt[]>>;
943
+ isConnected: Mock<() => boolean>;
944
+ getSessionContext: Mock<() => MCPSessionContext | null>;
945
+ }
946
+
947
+ /**
948
+ * Create a mock MCP client
949
+ */
950
+ export function createMockMCPClient(): MockMCPClient {
951
+ return {
952
+ connect: vi.fn().mockResolvedValue(undefined),
953
+ disconnect: vi.fn().mockResolvedValue(undefined),
954
+ callTool: vi.fn().mockResolvedValue(mcpToolResults.success),
955
+ listTools: vi.fn().mockResolvedValue(Object.values(mcpTools)),
956
+ readResource: vi.fn().mockResolvedValue({
957
+ type: 'resource',
958
+ resource: { uri: 'test://resource', text: '{}' },
959
+ }),
960
+ listResources: vi.fn().mockResolvedValue(Object.values(mcpResources)),
961
+ getPrompt: vi.fn().mockResolvedValue('Generated prompt text'),
962
+ listPrompts: vi.fn().mockResolvedValue(Object.values(mcpPrompts)),
963
+ isConnected: vi.fn().mockReturnValue(true),
964
+ getSessionContext: vi.fn().mockReturnValue(mcpSessionContexts.active),
965
+ };
966
+ }
967
+
968
+ /**
969
+ * Mock MCP server interface
970
+ */
971
+ export interface MockMCPServer {
972
+ start: Mock<() => Promise<void>>;
973
+ stop: Mock<() => Promise<void>>;
974
+ registerTool: Mock<(tool: MCPTool) => void>;
975
+ registerResource: Mock<(resource: MCPResource) => void>;
976
+ registerPrompt: Mock<(prompt: MCPPrompt) => void>;
977
+ handleRequest: Mock<(request: MCPRequestBase) => Promise<MCPResponseBase>>;
978
+ getStatus: Mock<() => MCPServerStatus>;
979
+ }
980
+
981
+ /**
982
+ * Create a mock MCP server
983
+ */
984
+ export function createMockMCPServer(): MockMCPServer {
985
+ return {
986
+ start: vi.fn().mockResolvedValue(undefined),
987
+ stop: vi.fn().mockResolvedValue(undefined),
988
+ registerTool: vi.fn(),
989
+ registerResource: vi.fn(),
990
+ registerPrompt: vi.fn(),
991
+ handleRequest: vi.fn().mockResolvedValue({
992
+ jsonrpc: '2.0',
993
+ id: 1,
994
+ result: { success: true },
995
+ }),
996
+ getStatus: vi.fn().mockReturnValue({
997
+ running: true,
998
+ transport: 'http',
999
+ connectedClients: 1,
1000
+ toolsRegistered: Object.keys(mcpTools).length,
1001
+ resourcesRegistered: Object.keys(mcpResources).length,
1002
+ promptsRegistered: Object.keys(mcpPrompts).length,
1003
+ requestsHandled: 100,
1004
+ errorsCount: 0,
1005
+ uptime: 3600000,
1006
+ }),
1007
+ };
1008
+ }
1009
+
1010
+ /**
1011
+ * Mock transport interface
1012
+ */
1013
+ export interface MockMCPTransport {
1014
+ send: Mock<(message: string) => Promise<void>>;
1015
+ receive: Mock<() => Promise<string>>;
1016
+ close: Mock<() => Promise<void>>;
1017
+ isOpen: Mock<() => boolean>;
1018
+ }
1019
+
1020
+ /**
1021
+ * Create a mock MCP transport
1022
+ */
1023
+ export function createMockMCPTransport(): MockMCPTransport {
1024
+ return {
1025
+ send: vi.fn().mockResolvedValue(undefined),
1026
+ receive: vi.fn().mockResolvedValue('{}'),
1027
+ close: vi.fn().mockResolvedValue(undefined),
1028
+ isOpen: vi.fn().mockReturnValue(true),
1029
+ };
1030
+ }