Skip to main content
Glama

task-orchestrator-mcp

by 108yen
table-display.test.ts14.5 kB
import { afterAll, beforeAll, beforeEach, describe, expect, it } from "vitest" import type { MCPResponse } from "./shared.js" import { clearAllTasks, client, parseMCPResponse, setupMCPConnection, } from "./shared.js" describe("Table Display Integration Tests", () => { beforeAll(async () => { await setupMCPConnection() }) beforeEach(() => { clearAllTasks() }) afterAll(() => { clearAllTasks() }) describe("Progress Table Display", () => { it("should display parent task name and status changed in progress table", async () => { // Create parent task const parentResult = await client.callTool({ arguments: { name: "Integration Parent Task" }, name: "createTask", }) const parentTask = parseMCPResponse(parentResult as MCPResponse).task // Create child task const childResult = await client.callTool({ arguments: { name: "Integration Child Task", parentId: parentTask.id, }, name: "createTask", }) const childTask = parseMCPResponse(childResult as MCPResponse).task // Start parent task await client.callTool({ arguments: { id: parentTask.id }, name: "startTask", }) // Complete child task to trigger progress summary const completeResult = await client.callTool({ arguments: { id: childTask.id, resolution: "Integration test completed", }, name: "completeTask", }) const response = parseMCPResponse(completeResult as MCPResponse) const progressTable = response.progress_summary.table // Verify new table format with additional columns expect(progressTable).toContain( "| Task Name | Parent Task | Status | Status Changed | Subtasks | Progress |", ) // Verify parent task shows no parent (-) expect(progressTable).toMatch( /\| Integration Parent Task \| - \| ✅ done \| ✓ \|/, ) // Verify status changed column exists and shows check mark expect(progressTable).toMatch(/✓/) // Verify subtasks and progress columns are present expect(progressTable).toContain("| 1/1 | 100% |") }) it("should handle hierarchical parent relationships in progress table", async () => { // Create multi-level hierarchy: Root -> Mid -> Leaf const rootResult = await client.callTool({ arguments: { name: "Root Level Task" }, name: "createTask", }) const rootTask = parseMCPResponse(rootResult as MCPResponse).task const midResult = await client.callTool({ arguments: { name: "Mid Level Task", parentId: rootTask.id, }, name: "createTask", }) const midTask = parseMCPResponse(midResult as MCPResponse).task const leafResult = await client.callTool({ arguments: { name: "Leaf Level Task", parentId: midTask.id, }, name: "createTask", }) const leafTask = parseMCPResponse(leafResult as MCPResponse).task // Start root task await client.callTool({ arguments: { id: rootTask.id }, name: "startTask", }) // Complete leaf task to trigger auto-completion of hierarchy const completeResult = await client.callTool({ arguments: { id: leafTask.id, resolution: "Leaf task completed", }, name: "completeTask", }) const response = parseMCPResponse(completeResult as MCPResponse) const progressTable = response.progress_summary.table // Verify both parent tasks show correct parent relationships expect(progressTable).toMatch( /\| Root Level Task \| - \| ✅ done \| ✓ \|/, ) expect(progressTable).toMatch( /\| Mid Level Task \| Root Level Task \| ✅ done \| ✓ \|/, ) // Both should show 100% completion expect(progressTable).toMatch(/\| 1\/1 \| 100% \|.*\| 1\/1 \| 100% \|/s) }) it("should handle multiple siblings with same parent in progress table", async () => { // Create parent with multiple children const parentResult = await client.callTool({ arguments: { name: "Multi-Child Parent" }, name: "createTask", }) const parentTask = parseMCPResponse(parentResult as MCPResponse).task // Create multiple children const child1Result = await client.callTool({ arguments: { name: "First Child", parentId: parentTask.id, }, name: "createTask", }) const child1Task = parseMCPResponse(child1Result as MCPResponse).task const child2Result = await client.callTool({ arguments: { name: "Second Child", parentId: parentTask.id, }, name: "createTask", }) const child2Task = parseMCPResponse(child2Result as MCPResponse).task // Start parent task await client.callTool({ arguments: { id: parentTask.id }, name: "startTask", }) // Complete first child await client.callTool({ arguments: { id: child1Task.id, resolution: "First child done", }, name: "completeTask", }) // Complete second child const completeResult = await client.callTool({ arguments: { id: child2Task.id, resolution: "Second child done", }, name: "completeTask", }) const response = parseMCPResponse(completeResult as MCPResponse) const progressTable = response.progress_summary.table // Verify parent shows correct count of completed subtasks expect(progressTable).toContain( "| Multi-Child Parent | - | ✅ done | ✓ | 2/2 | 100% |", ) }) }) describe("Hierarchy Table Display", () => { it("should display parent task name and status changed in hierarchy summary", async () => { // Create hierarchical structure const rootResult = await client.callTool({ arguments: { name: "Hierarchy Root" }, name: "createTask", }) const rootTask = parseMCPResponse(rootResult as MCPResponse).task const branchResult = await client.callTool({ arguments: { name: "Hierarchy Branch", parentId: rootTask.id, }, name: "createTask", }) const branchTask = parseMCPResponse(branchResult as MCPResponse).task await client.callTool({ arguments: { name: "Hierarchy Leaf", parentId: branchTask.id, }, name: "createTask", }) // Start root task to get hierarchy summary const startResult = await client.callTool({ arguments: { id: rootTask.id }, name: "startTask", }) const response = parseMCPResponse(startResult as MCPResponse) const hierarchySummary = response.hierarchy_summary // Verify new table format with additional columns expect(hierarchySummary).toContain( "| Task Name | Parent Task | Status | Status Changed | Subtasks | Progress |", ) // Verify root task shows no parent expect(hierarchySummary).toMatch(/Hierarchy Root.*\| - \|.*in_progress/) // Verify branch shows root as parent expect(hierarchySummary).toMatch( /Hierarchy Branch.*\| Hierarchy Root \|.*in_progress/, ) // Verify leaf shows branch as parent expect(hierarchySummary).toMatch( /Hierarchy Leaf.*\| Hierarchy Branch \|.*in_progress/, ) // Verify all entries have status change indicators expect(hierarchySummary).toMatch(/✓/) }) it("should display task names without indentation but with parent names", async () => { // Create deep hierarchy: L1 -> L2 -> L3 -> L4 const level1Result = await client.callTool({ arguments: { name: "Level 1" }, name: "createTask", }) const level1Task = parseMCPResponse(level1Result as MCPResponse).task const level2Result = await client.callTool({ arguments: { name: "Level 2", parentId: level1Task.id, }, name: "createTask", }) const level2Task = parseMCPResponse(level2Result as MCPResponse).task const level3Result = await client.callTool({ arguments: { name: "Level 3", parentId: level2Task.id, }, name: "createTask", }) const level3Task = parseMCPResponse(level3Result as MCPResponse).task await client.callTool({ arguments: { name: "Level 4", parentId: level3Task.id, }, name: "createTask", }) // Start level 1 task const startResult = await client.callTool({ arguments: { id: level1Task.id }, name: "startTask", }) const response = parseMCPResponse(startResult as MCPResponse) const hierarchySummary = response.hierarchy_summary // Verify task names are displayed without indentation (like completeTask format) expect(hierarchySummary).toMatch(/\| Level 1 \| - \|/) // No indentation expect(hierarchySummary).toMatch(/\| Level 2 \| Level 1 \|/) // No indentation expect(hierarchySummary).toMatch(/\| Level 3 \| Level 2 \|/) // No indentation expect(hierarchySummary).toMatch(/\| Level 4 \| Level 3 \|/) // No indentation }) it("should handle complex branching hierarchy with flat task names", async () => { // Create branching structure: Main -> (Branch A, Branch B) -> (Leaf A1, Leaf A2, Leaf B1) const mainResult = await client.callTool({ arguments: { name: "Main Branch" }, name: "createTask", }) const mainTask = parseMCPResponse(mainResult as MCPResponse).task const branchAResult = await client.callTool({ arguments: { name: "Branch A", parentId: mainTask.id, }, name: "createTask", }) const branchATask = parseMCPResponse(branchAResult as MCPResponse).task const branchBResult = await client.callTool({ arguments: { name: "Branch B", parentId: mainTask.id, }, name: "createTask", }) const branchBTask = parseMCPResponse(branchBResult as MCPResponse).task // Create leaves for Branch A await client.callTool({ arguments: { name: "Leaf A1", parentId: branchATask.id, }, name: "createTask", }) await client.callTool({ arguments: { name: "Leaf A2", parentId: branchATask.id, }, name: "createTask", }) // Create leaf for Branch B await client.callTool({ arguments: { name: "Leaf B1", parentId: branchBTask.id, }, name: "createTask", }) // Start main task const startResult = await client.callTool({ arguments: { id: mainTask.id }, name: "startTask", }) const response = parseMCPResponse(startResult as MCPResponse) const hierarchySummary = response.hierarchy_summary // Verify all parent relationships are correct expect(hierarchySummary).toMatch(/Main Branch.*\| - \|/) expect(hierarchySummary).toMatch(/Branch A.*\| Main Branch \|/) expect(hierarchySummary).toMatch(/Branch B.*\| Main Branch \|/) expect(hierarchySummary).toMatch(/Leaf A1.*\| Branch A \|/) expect(hierarchySummary).toMatch(/Leaf A2.*\| Branch A \|/) expect(hierarchySummary).toMatch(/Leaf B1.*\| Branch B \|/) // Verify task names are displayed without indentation (like completeTask format) expect(hierarchySummary).toMatch(/\| Main Branch \| - \|/) // Level 0 expect(hierarchySummary).toMatch(/\| Branch A \| Main Branch \|/) // Level 1 - no indentation expect(hierarchySummary).toMatch(/\| Branch B \| Main Branch \|/) // Level 1 - no indentation expect(hierarchySummary).toMatch(/\| Leaf A1 \| Branch A \|/) // Level 2 - no indentation expect(hierarchySummary).toMatch(/\| Leaf A2 \| Branch A \|/) // Level 2 - no indentation expect(hierarchySummary).toMatch(/\| Leaf B1 \| Branch B \|/) // Level 2 - no indentation }) }) describe("Status Changed Column Accuracy", () => { it("should update status changed indicator when task status changes", async () => { // Create a task const taskResult = await client.callTool({ arguments: { name: "Timestamp Test Task" }, name: "createTask", }) const task = parseMCPResponse(taskResult as MCPResponse).task // Create child task const childResult = await client.callTool({ arguments: { name: "Timestamp Child Task", parentId: task.id, }, name: "createTask", }) const childTask = parseMCPResponse(childResult as MCPResponse).task // Start task (changes status from todo to in_progress) const startResult = await client.callTool({ arguments: { id: task.id }, name: "startTask", }) const startResponse = parseMCPResponse(startResult as MCPResponse) const startHierarchy = startResponse.hierarchy_summary // Extract status change indicator from the table const statusChangeMatch = startHierarchy.match( /Timestamp Test Task.*?\| - \| ⚡ in_progress \| ✓ \|/, ) expect(statusChangeMatch).toBeTruthy() // Verify the task shows as status changed since it was started expect(startHierarchy).toContain("✓") // Complete child task to trigger status change for parent await new Promise((resolve) => setTimeout(resolve, 100)) const completeResult = await client.callTool({ arguments: { id: childTask.id, resolution: "Status timestamp test", }, name: "completeTask", }) const completeResponse = parseMCPResponse(completeResult as MCPResponse) const progressTable = completeResponse.progress_summary.table // Extract completion status change indicator const completeStatusChangeMatch = progressTable.match( /\| Timestamp Test Task \| - \| ✅ done \| ✓ \|/, ) expect(completeStatusChangeMatch).toBeTruthy() // Verify both status changes are indicated with check marks expect(startHierarchy).toContain("✓") expect(progressTable).toContain("✓") }) }) })

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/108yen/task-orchestrator-mcp'

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