UNPKG

@smartsheet/smar-mcp

Version:

A Model Context Protocol (MCP) server for interacting with the Smartsheet API. This server provides tools for searching, retrieving, and updating Smartsheet sheets through the MCP protocol.

228 lines (227 loc) 11.7 kB
import { createProjectPlanPrompt, generateSprintReportPrompt, optimizeTaskAssignmentPrompt, analyzeProjectRisksPrompt, optimizeDevWorkflowPrompt, registerCorePrompts } from '../core-prompts.js'; import { promptRegistry, TemplateEngine } from '../prompt-handler.js'; describe('Core Prompts', () => { beforeEach(() => { // Clear the global registry before each test promptRegistry.prompts.clear(); }); describe('registerCorePrompts', () => { it('should register all 5 core prompts', () => { registerCorePrompts(); expect(promptRegistry.has('create_project_plan')).toBe(true); expect(promptRegistry.has('generate_sprint_report')).toBe(true); expect(promptRegistry.has('optimize_task_assignment')).toBe(true); expect(promptRegistry.has('analyze_project_risks')).toBe(true); expect(promptRegistry.has('optimize_dev_workflow')).toBe(true); const allPrompts = promptRegistry.getAll(); expect(allPrompts).toHaveLength(5); }); }); describe('createProjectPlanPrompt', () => { it('should have correct basic properties', () => { expect(createProjectPlanPrompt.name).toBe('create_project_plan'); expect(createProjectPlanPrompt.description).toContain('structured project breakdowns'); expect(createProjectPlanPrompt.category).toBe('project_management'); expect(createProjectPlanPrompt.version).toBe('1.0.0'); }); it('should have required arguments', () => { const args = createProjectPlanPrompt.arguments || []; const requiredArgs = args.filter(arg => arg.required); expect(requiredArgs).toHaveLength(3); expect(requiredArgs.map(arg => arg.name)).toEqual([ 'project_description', 'timeline', 'team_size' ]); }); it('should have optional arguments', () => { const args = createProjectPlanPrompt.arguments || []; const optionalArgs = args.filter(arg => !arg.required); expect(optionalArgs.map(arg => arg.name)).toEqual([ 'budget_constraints', 'technology_stack' ]); }); it('should substitute template variables correctly', () => { const variables = { project_description: 'E-commerce website', timeline: '3 months', team_size: 5, budget_constraints: '$50,000', technology_stack: 'React, Node.js' }; const result = TemplateEngine.substitute(createProjectPlanPrompt.template, variables); expect(result).toContain('E-commerce website'); expect(result).toContain('3 months'); expect(result).toContain('5'); expect(result).toContain('$50,000'); expect(result).toContain('React, Node.js'); }); }); describe('generateSprintReportPrompt', () => { it('should have correct basic properties', () => { expect(generateSprintReportPrompt.name).toBe('generate_sprint_report'); expect(generateSprintReportPrompt.description).toContain('sprint status summaries'); expect(generateSprintReportPrompt.category).toBe('agile_management'); }); it('should require sheet_data and sprint_length', () => { const args = generateSprintReportPrompt.arguments || []; const requiredArgs = args.filter(arg => arg.required); expect(requiredArgs.map(arg => arg.name)).toEqual([ 'sheet_data', 'sprint_length' ]); }); it('should handle object type for sheet_data', () => { const args = generateSprintReportPrompt.arguments || []; const sheetDataArg = args.find(arg => arg.name === 'sheet_data'); expect(sheetDataArg?.type).toBe('object'); expect(sheetDataArg?.required).toBe(true); }); }); describe('optimizeTaskAssignmentPrompt', () => { it('should have correct basic properties', () => { expect(optimizeTaskAssignmentPrompt.name).toBe('optimize_task_assignment'); expect(optimizeTaskAssignmentPrompt.description).toContain('resource allocation'); expect(optimizeTaskAssignmentPrompt.category).toBe('resource_management'); }); it('should require team and task data', () => { const args = optimizeTaskAssignmentPrompt.arguments || []; const requiredArgs = args.filter(arg => arg.required); expect(requiredArgs.map(arg => arg.name)).toEqual([ 'team_members', 'task_list', 'skills_data', 'workload_data' ]); }); it('should handle array and object types correctly', () => { const args = optimizeTaskAssignmentPrompt.arguments || []; const teamMembersArg = args.find(arg => arg.name === 'team_members'); expect(teamMembersArg?.type).toBe('array'); const skillsDataArg = args.find(arg => arg.name === 'skills_data'); expect(skillsDataArg?.type).toBe('object'); }); }); describe('analyzeProjectRisksPrompt', () => { it('should have correct basic properties', () => { expect(analyzeProjectRisksPrompt.name).toBe('analyze_project_risks'); expect(analyzeProjectRisksPrompt.description).toContain('risk identification'); expect(analyzeProjectRisksPrompt.category).toBe('risk_management'); }); it('should require core project information', () => { const args = analyzeProjectRisksPrompt.arguments || []; const requiredArgs = args.filter(arg => arg.required); expect(requiredArgs.map(arg => arg.name)).toEqual([ 'project_scope', 'current_progress', 'team_info', 'project_timeline' ]); }); it('should have optional budget and stakeholder info', () => { const args = analyzeProjectRisksPrompt.arguments || []; const optionalArgs = args.filter(arg => !arg.required); expect(optionalArgs.map(arg => arg.name)).toEqual([ 'budget_info', 'stakeholder_info' ]); }); }); describe('optimizeDevWorkflowPrompt', () => { it('should have correct basic properties', () => { expect(optimizeDevWorkflowPrompt.name).toBe('optimize_dev_workflow'); expect(optimizeDevWorkflowPrompt.description).toContain('Process improvement'); expect(optimizeDevWorkflowPrompt.category).toBe('process_optimization'); }); it('should require workflow analysis data', () => { const args = optimizeDevWorkflowPrompt.arguments || []; const requiredArgs = args.filter(arg => arg.required); expect(requiredArgs.map(arg => arg.name)).toEqual([ 'workflow_metrics', 'dev_practices', 'tool_stack', 'bottleneck_data' ]); }); it('should have optional team feedback and targets', () => { const args = optimizeDevWorkflowPrompt.arguments || []; const optionalArgs = args.filter(arg => !arg.required); expect(optionalArgs.map(arg => arg.name)).toEqual([ 'team_feedback', 'delivery_targets' ]); }); }); describe('Template Variable Extraction', () => { it('should extract all variables from create_project_plan template', () => { const variables = TemplateEngine.extractVariables(createProjectPlanPrompt.template); expect(variables).toContain('project_description'); expect(variables).toContain('timeline'); expect(variables).toContain('team_size'); expect(variables).toContain('budget_constraints'); expect(variables).toContain('technology_stack'); }); it('should extract all variables from generate_sprint_report template', () => { const variables = TemplateEngine.extractVariables(generateSprintReportPrompt.template); expect(variables).toContain('sheet_data'); expect(variables).toContain('sprint_length'); expect(variables).toContain('sprint_goal'); expect(variables).toContain('previous_velocity'); }); it('should extract all variables from optimize_task_assignment template', () => { const variables = TemplateEngine.extractVariables(optimizeTaskAssignmentPrompt.template); expect(variables).toContain('team_members'); expect(variables).toContain('task_list'); expect(variables).toContain('skills_data'); expect(variables).toContain('workload_data'); expect(variables).toContain('project_deadline'); }); }); describe('Template Validation', () => { it('should validate create_project_plan with all required variables', () => { const variables = { project_description: 'Test project', timeline: '2 months', team_size: 3, budget_constraints: 'N/A', // Include optional parameters that are in template technology_stack: 'React' }; const validation = TemplateEngine.validateVariables(createProjectPlanPrompt.template, variables, createProjectPlanPrompt.arguments); expect(validation.isValid).toBe(true); expect(validation.missingVariables).toEqual([]); }); it('should identify missing required variables', () => { const variables = { project_description: 'Test project' // Missing timeline and team_size }; const validation = TemplateEngine.validateVariables(createProjectPlanPrompt.template, variables, createProjectPlanPrompt.arguments); expect(validation.isValid).toBe(false); expect(validation.missingVariables).toContain('timeline'); expect(validation.missingVariables).toContain('team_size'); }); }); describe('Prompt Categories', () => { beforeEach(() => { registerCorePrompts(); }); it('should organize prompts by categories', () => { const projectMgmtPrompts = promptRegistry.getByCategory('project_management'); expect(projectMgmtPrompts).toHaveLength(1); expect(projectMgmtPrompts[0].name).toBe('create_project_plan'); const agileMgmtPrompts = promptRegistry.getByCategory('agile_management'); expect(agileMgmtPrompts).toHaveLength(1); expect(agileMgmtPrompts[0].name).toBe('generate_sprint_report'); const resourceMgmtPrompts = promptRegistry.getByCategory('resource_management'); expect(resourceMgmtPrompts).toHaveLength(1); expect(resourceMgmtPrompts[0].name).toBe('optimize_task_assignment'); const riskMgmtPrompts = promptRegistry.getByCategory('risk_management'); expect(riskMgmtPrompts).toHaveLength(1); expect(riskMgmtPrompts[0].name).toBe('analyze_project_risks'); const processOptPrompts = promptRegistry.getByCategory('process_optimization'); expect(processOptPrompts).toHaveLength(1); expect(processOptPrompts[0].name).toBe('optimize_dev_workflow'); }); }); });