Skip to main content
Glama
blizzy78
by blizzy78
task_info.test.ts13.6 kB
import { beforeEach, describe, expect, it } from 'vitest' import { TaskDB } from '../task_db.js' import { DoneStatus, InProgressStatus, newTaskID, TodoStatus, type Task } from '../tasks.js' import { handleTaskInfo } from './task_info.js' describe('task_info tool handler', () => { let taskDB: TaskDB beforeEach(() => { taskDB = new TaskDB() }) describe('single task retrieval', () => { it('should return full task details for existing task', async () => { const taskID = newTaskID() const task: Task = { taskID, status: TodoStatus, dependsOnTaskIDs: [], title: 'Test Task', description: 'Test task description', goal: 'Test goal', definitionsOfDone: ['Task is complete'], criticalPath: true, uncertaintyAreas: [ { title: 'Test uncertainty', description: 'Test uncertainty description', }, ], estimatedComplexity: { level: 'medium, must decompose before execution', description: 'Medium complexity task', }, lessonsLearned: ['Test lesson'], verificationEvidence: ['Test evidence'], } taskDB.set(taskID, task) const args = { taskIDs: [taskID], } const result = await handleTaskInfo(args, taskDB, false) expect(result.content).toEqual([]) expect(result.structuredContent).toMatchObject({ tasks: [task], notFoundTasks: [], }) }) it('should handle non-existent task', async () => { const nonExistentID = newTaskID() const args = { taskIDs: [nonExistentID], } const result = await handleTaskInfo(args, taskDB, false) expect(result.structuredContent).toMatchObject({ tasks: [], notFoundTasks: [nonExistentID], }) }) }) describe('multiple task retrieval', () => { it('should return multiple existing tasks', async () => { const task1ID = newTaskID() const task1: Task = { taskID: task1ID, status: TodoStatus, dependsOnTaskIDs: [], title: 'First Task', description: 'First task description', goal: 'First goal', definitionsOfDone: ['First done'], criticalPath: true, uncertaintyAreas: [], lessonsLearned: [], verificationEvidence: [], } taskDB.set(task1ID, task1) const task2ID = newTaskID() const task2: Task = { taskID: task2ID, status: InProgressStatus, dependsOnTaskIDs: [task1ID], title: 'Second Task', description: 'Second task description', goal: 'Second goal', definitionsOfDone: ['Second done'], criticalPath: false, uncertaintyAreas: [], lessonsLearned: ['Second lesson'], verificationEvidence: [], } taskDB.set(task2ID, task2) const task3ID = newTaskID() const task3: Task = { taskID: task3ID, status: DoneStatus, dependsOnTaskIDs: [], title: 'Third Task', description: 'Third task description', goal: 'Third goal', definitionsOfDone: ['Third done'], criticalPath: true, uncertaintyAreas: [], lessonsLearned: [], verificationEvidence: ['Third evidence'], } taskDB.set(task3ID, task3) const args = { taskIDs: [task1ID, task2ID, task3ID], } const result = await handleTaskInfo(args, taskDB, false) expect(result.structuredContent.tasks).toHaveLength(3) expect(result.structuredContent.notFoundTasks).toHaveLength(0) expect(result.structuredContent.tasks).toContainEqual(task1) expect(result.structuredContent.tasks).toContainEqual(task2) expect(result.structuredContent.tasks).toContainEqual(task3) }) it('should handle mix of existing and non-existent tasks', async () => { const existingTaskID = newTaskID() const existingTask: Task = { taskID: existingTaskID, status: TodoStatus, dependsOnTaskIDs: [], title: 'Existing Task', description: 'This task exists', goal: 'Existing goal', definitionsOfDone: ['Existing done'], criticalPath: true, uncertaintyAreas: [], lessonsLearned: [], verificationEvidence: [], } taskDB.set(existingTaskID, existingTask) const nonExistentID1 = newTaskID() const nonExistentID2 = newTaskID() const args = { taskIDs: [existingTaskID, nonExistentID1, nonExistentID2], } const result = await handleTaskInfo(args, taskDB, false) expect(result.structuredContent.tasks).toHaveLength(1) expect(result.structuredContent.tasks[0]).toEqual(existingTask) expect(result.structuredContent.notFoundTasks).toHaveLength(2) expect(result.structuredContent.notFoundTasks).toContain(nonExistentID1) expect(result.structuredContent.notFoundTasks).toContain(nonExistentID2) }) it('should handle all non-existent tasks', async () => { const nonExistentID1 = newTaskID() const nonExistentID2 = newTaskID() const nonExistentID3 = newTaskID() const args = { taskIDs: [nonExistentID1, nonExistentID2, nonExistentID3], } const result = await handleTaskInfo(args, taskDB, false) expect(result.structuredContent.tasks).toHaveLength(0) expect(result.structuredContent.notFoundTasks).toHaveLength(3) expect(result.structuredContent.notFoundTasks).toContain(nonExistentID1) expect(result.structuredContent.notFoundTasks).toContain(nonExistentID2) expect(result.structuredContent.notFoundTasks).toContain(nonExistentID3) }) }) describe('task details completeness', () => { it('should return all task properties', async () => { const depTaskID = newTaskID() const depTask: Task = { taskID: depTaskID, status: DoneStatus, dependsOnTaskIDs: [], title: 'Dependency Task', description: 'Task that is a dependency', goal: 'Dependency goal', definitionsOfDone: ['Dependency done'], criticalPath: true, uncertaintyAreas: [], lessonsLearned: [], verificationEvidence: [], } taskDB.set(depTaskID, depTask) const taskID = newTaskID() const task: Task = { taskID, status: InProgressStatus, dependsOnTaskIDs: [depTaskID], title: 'Complete Task', description: 'Task with all properties', goal: 'Complete goal', definitionsOfDone: ['First criterion', 'Second criterion'], criticalPath: true, uncertaintyAreas: [ { title: 'First uncertainty', description: 'First uncertainty description', }, { title: 'Second uncertainty', description: 'Second uncertainty description', }, ], estimatedComplexity: { level: 'high, must decompose before execution', description: 'Very complex task', }, lessonsLearned: ['First lesson', 'Second lesson'], verificationEvidence: ['First evidence', 'Second evidence'], } taskDB.set(taskID, task) const args = { taskIDs: [taskID], } const result = await handleTaskInfo(args, taskDB, false) const returnedTask = result.structuredContent.tasks[0] expect(returnedTask).toEqual(task) expect(returnedTask.taskID).toBe(taskID) expect(returnedTask.status).toBe(InProgressStatus) expect(returnedTask.dependsOnTaskIDs).toEqual([depTaskID]) expect(returnedTask.title).toBe('Complete Task') expect(returnedTask.description).toBe('Task with all properties') expect(returnedTask.goal).toBe('Complete goal') expect(returnedTask.definitionsOfDone).toEqual(['First criterion', 'Second criterion']) expect(returnedTask.criticalPath).toBe(true) expect(returnedTask.uncertaintyAreas).toHaveLength(2) expect(returnedTask.estimatedComplexity).toMatchObject({ level: 'high, must decompose before execution', description: 'Very complex task', }) expect(returnedTask.lessonsLearned).toEqual(['First lesson', 'Second lesson']) expect(returnedTask.verificationEvidence).toEqual(['First evidence', 'Second evidence']) }) it('should return task with minimal properties', async () => { const taskID = newTaskID() const task: Task = { taskID, status: TodoStatus, dependsOnTaskIDs: [], title: 'Minimal Task', description: 'Minimal description', goal: 'Minimal goal', definitionsOfDone: ['Minimal done'], criticalPath: false, uncertaintyAreas: [], lessonsLearned: [], verificationEvidence: [], } taskDB.set(taskID, task) const args = { taskIDs: [taskID], } const result = await handleTaskInfo(args, taskDB, false) const returnedTask = result.structuredContent.tasks[0] expect(returnedTask).toEqual(task) expect(returnedTask.uncertaintyAreas).toEqual([]) expect(returnedTask.lessonsLearned).toEqual([]) expect(returnedTask.verificationEvidence).toEqual([]) expect(returnedTask.estimatedComplexity).toBeUndefined() }) }) describe('task ordering', () => { it('should return tasks in the order they were requested', async () => { const task1ID = newTaskID() const task1: Task = { taskID: task1ID, status: TodoStatus, dependsOnTaskIDs: [], title: 'First Task', description: 'First', goal: 'First goal', definitionsOfDone: ['First done'], criticalPath: true, uncertaintyAreas: [], lessonsLearned: [], verificationEvidence: [], } taskDB.set(task1ID, task1) const task2ID = newTaskID() const task2: Task = { taskID: task2ID, status: InProgressStatus, dependsOnTaskIDs: [], title: 'Second Task', description: 'Second', goal: 'Second goal', definitionsOfDone: ['Second done'], criticalPath: false, uncertaintyAreas: [], lessonsLearned: [], verificationEvidence: [], } taskDB.set(task2ID, task2) const task3ID = newTaskID() const task3: Task = { taskID: task3ID, status: DoneStatus, dependsOnTaskIDs: [], title: 'Third Task', description: 'Third', goal: 'Third goal', definitionsOfDone: ['Third done'], criticalPath: true, uncertaintyAreas: [], lessonsLearned: [], verificationEvidence: [], } taskDB.set(task3ID, task3) // Request in specific order const args = { taskIDs: [task3ID, task1ID, task2ID], } const result = await handleTaskInfo(args, taskDB, false) expect(result.structuredContent.tasks).toHaveLength(3) expect(result.structuredContent.tasks[0].taskID).toBe(task3ID) expect(result.structuredContent.tasks[1].taskID).toBe(task1ID) expect(result.structuredContent.tasks[2].taskID).toBe(task2ID) }) }) describe('edge cases', () => { it('should handle duplicate task IDs', async () => { const taskID = newTaskID() const task: Task = { taskID, status: TodoStatus, dependsOnTaskIDs: [], title: 'Duplicate Test Task', description: 'Testing duplicates', goal: 'Duplicate goal', definitionsOfDone: ['Duplicate done'], criticalPath: true, uncertaintyAreas: [], lessonsLearned: [], verificationEvidence: [], } taskDB.set(taskID, task) const args = { taskIDs: [taskID, taskID, taskID], // Same ID multiple times } const result = await handleTaskInfo(args, taskDB, false) // Should return the task multiple times as requested expect(result.structuredContent.tasks).toHaveLength(3) expect(result.structuredContent.tasks[0]).toEqual(task) expect(result.structuredContent.tasks[1]).toEqual(task) expect(result.structuredContent.tasks[2]).toEqual(task) expect(result.structuredContent.notFoundTasks).toHaveLength(0) }) it('should handle mix of duplicate existing and non-existent IDs', async () => { const existingTaskID = newTaskID() const existingTask: Task = { taskID: existingTaskID, status: TodoStatus, dependsOnTaskIDs: [], title: 'Existing Task', description: 'Exists', goal: 'Existing goal', definitionsOfDone: ['Existing done'], criticalPath: true, uncertaintyAreas: [], lessonsLearned: [], verificationEvidence: [], } taskDB.set(existingTaskID, existingTask) const nonExistentID = newTaskID() const args = { taskIDs: [existingTaskID, nonExistentID, existingTaskID, nonExistentID], } const result = await handleTaskInfo(args, taskDB, false) expect(result.structuredContent.tasks).toHaveLength(2) expect(result.structuredContent.tasks[0]).toEqual(existingTask) expect(result.structuredContent.tasks[1]).toEqual(existingTask) expect(result.structuredContent.notFoundTasks).toHaveLength(2) expect(result.structuredContent.notFoundTasks[0]).toBe(nonExistentID) expect(result.structuredContent.notFoundTasks[1]).toBe(nonExistentID) }) }) })

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/blizzy78/mcp-task-manager'

If you have feedback or need assistance with the MCP directory API, please join our Discord server