@boundless-oss/atlas
Version:
Atlas - MCP Server for comprehensive startup project management
188 lines (167 loc) • 6.86 kB
text/typescript
import { describe, it, expect, beforeEach, vi } from 'vitest';
import { setupProductRequirementsTools } from '../tools.js';
import { SqliteManager } from '../../../storage/sqlite-manager.js';
// Mock SqliteManager
vi.mock('../../../storage/sqlite-manager.js', () => ({
SqliteManager: {
getInstance: vi.fn()
}
}));
describe('Product Requirements Module', () => {
let tools: any;
let mockDb: vi.Mocked<SqliteManager>;
let module: any;
beforeEach(async () => {
vi.clearAllMocks();
// Mock database operations
mockDb = {
run: vi.fn().mockResolvedValue({ success: true, changes: 1 }),
get: vi.fn().mockResolvedValue({ success: true, data: null }),
query: vi.fn().mockResolvedValue({ success: true, data: [] }),
transaction: vi.fn().mockImplementation(async (callback) => {
return await callback(mockDb);
})
} as any;
vi.mocked(SqliteManager.getInstance).mockReturnValue(mockDb);
// Setup tools
const toolRegistration = await setupProductRequirementsTools();
module = toolRegistration;
tools = {};
for (const tool of toolRegistration.tools) {
tools[tool.name] = tool;
}
});
const createContext = (toolName: string) => ({
toolName,
requestId: 'test-req-1',
projectId: 'test-project',
userId: 'test-user',
timestamp: Date.now(),
db: mockDb
});
describe('Module Setup', () => {
it('should return tools', () => {
expect(module).toHaveProperty('tools');
expect(module.tools).toBeInstanceOf(Array);
});
it('should register all required tools', () => {
const toolNames = module.tools.map((t: any) => t.name);
expect(toolNames).toContain('create_requirement');
expect(toolNames).toContain('list_requirements');
expect(toolNames).toContain('get_requirement');
expect(toolNames).toContain('update_requirement');
expect(toolNames).toContain('delete_requirement');
expect(toolNames).toContain('search_requirements');
expect(toolNames).toContain('link_requirement_to_story');
expect(toolNames).toContain('update_implementation_status');
expect(toolNames).toContain('generate_requirements_report');
});
});
describe('create_requirement tool', () => {
it('should have correct schema', () => {
const tool = module.tools.find((t: any) => t.name === 'create_requirement');
expect(tool).toBeDefined();
expect(tool.inputSchema.required).toContain('name');
expect(tool.inputSchema.required).toContain('type');
expect(tool.inputSchema.required).toContain('description');
});
it('should validate requirement types', () => {
const tool = tools.create_requirement;
const typeEnum = tool.inputSchema.properties.type.enum;
expect(typeEnum).toContain('functional');
expect(typeEnum).toContain('non-functional');
expect(typeEnum).toContain('business');
expect(typeEnum).toContain('technical');
expect(typeEnum).toContain('user-interface');
expect(typeEnum).toContain('security');
expect(typeEnum).toContain('performance');
});
it('should handle requirement creation', async () => {
const input = {
name: 'User Authentication',
type: 'functional' as const,
description: 'Users should be able to log in with email and password',
acceptanceCriteria: [
'Email validation',
'Password strength requirements',
'Remember me option'
],
priority: 'high' as const,
status: 'draft' as const,
repositories: [
{
name: 'backend-api',
implementationStatus: 'not_started' as const,
branch: 'feat/auth'
}
]
};
const result = await tools.create_requirement.execute(input, createContext('create_requirement'));
expect(result.success).toBe(true);
expect(result.data.requirement.name).toBe('User Authentication');
expect(result.data.requirement.type).toBe('functional');
expect(mockDb.run).toHaveBeenCalled();
});
});
describe('list_requirements tool', () => {
it('should have correct schema', () => {
const tool = tools.list_requirements;
expect(tool).toBeDefined();
expect(tool.inputSchema.properties).toHaveProperty('filterByType');
expect(tool.inputSchema.properties).toHaveProperty('filterByStatus');
expect(tool.inputSchema.properties).toHaveProperty('filterByPriority');
});
});
describe('update_requirement tool', () => {
it('should have correct schema', () => {
const tool = tools.update_requirement;
expect(tool).toBeDefined();
expect(tool.inputSchema.required).toContain('id');
expect(tool.inputSchema.properties).toHaveProperty('name');
expect(tool.inputSchema.properties).toHaveProperty('description');
expect(tool.inputSchema.properties).toHaveProperty('status');
});
});
describe('link_requirement_to_story tool', () => {
it('should have correct schema', () => {
const tool = tools.link_requirement_to_story;
expect(tool).toBeDefined();
expect(tool.inputSchema.required).toContain('requirementId');
expect(tool.inputSchema.required).toContain('storyId');
});
});
describe('update_implementation_status tool', () => {
it('should have correct schema', () => {
const tool = tools.update_implementation_status;
expect(tool).toBeDefined();
expect(tool.inputSchema.required).toContain('requirementId');
expect(tool.inputSchema.required).toContain('repositoryName');
expect(tool.inputSchema.required).toContain('status');
});
it('should validate implementation status values', () => {
const tool = tools.update_implementation_status;
const statusEnum = tool.inputSchema.properties.status.enum;
expect(statusEnum).toContain('not_started');
expect(statusEnum).toContain('in_progress');
expect(statusEnum).toContain('completed');
expect(statusEnum).toContain('blocked');
});
});
describe('search_requirements tool', () => {
it('should have correct schema', () => {
const tool = tools.search_requirements;
expect(tool).toBeDefined();
expect(tool.inputSchema.required).toContain('query');
expect(tool.inputSchema.properties).toHaveProperty('searchIn');
});
});
describe('generate_requirements_report tool', () => {
it('should have correct schema', () => {
const tool = tools.generate_requirements_report;
expect(tool).toBeDefined();
expect(tool.inputSchema.properties).toHaveProperty('format');
expect(tool.inputSchema.properties).toHaveProperty('includeImplementationStatus');
expect(tool.inputSchema.properties).toHaveProperty('groupBy');
});
});
});