Skip to main content
Glama

Task Trellis MCP

getObjectFilePath.test.ts10.4 kB
import { join } from "path"; import { TrellisObject, TrellisObjectPriority, TrellisObjectStatus, TrellisObjectType, } from "../../../models"; import * as getObjectByIdModule from "../getObjectById"; import { getObjectFilePath } from "../getObjectFilePath"; // Mock the getObjectById function jest.mock("../getObjectById"); const mockGetObjectById = jest.mocked(getObjectByIdModule.getObjectById); describe("getObjectFilePath", () => { const testPlanningRoot = "/test/planning/root"; beforeEach(() => { jest.clearAllMocks(); }); const createMockObject = ( id: string, type: TrellisObjectType, parent: string | null = null, status: TrellisObjectStatus = TrellisObjectStatus.OPEN, ): TrellisObject => ({ id, type, title: `Test ${id}`, status, priority: TrellisObjectPriority.MEDIUM, parent, prerequisites: [], affectedFiles: new Map(), log: [], schema: "1.0", childrenIds: [], body: "", created: "2025-01-15T10:00:00Z", updated: "2025-01-15T10:00:00Z", }); describe("Project objects", () => { it("should return correct path for project", async () => { const project = createMockObject( "P-test-project", TrellisObjectType.PROJECT, ); const result = await getObjectFilePath(project, testPlanningRoot); expect(result).toBe( join(testPlanningRoot, "p", "P-test-project", "P-test-project.md"), ); }); }); describe("Epic objects", () => { it("should return correct path for epic with parent", async () => { const epic = createMockObject( "E-test-epic", TrellisObjectType.EPIC, "P-test-project", ); const result = await getObjectFilePath(epic, testPlanningRoot); expect(result).toBe( join( testPlanningRoot, "p", "P-test-project", "e", "E-test-epic", "E-test-epic.md", ), ); }); it("should return correct path for standalone epic", async () => { const epic = createMockObject("E-test-epic", TrellisObjectType.EPIC); const result = await getObjectFilePath(epic, testPlanningRoot); expect(result).toBe( join(testPlanningRoot, "e", "E-test-epic", "E-test-epic.md"), ); }); }); describe("Feature objects", () => { it("should return correct path for standalone feature", async () => { const feature = createMockObject( "F-test-feature", TrellisObjectType.FEATURE, ); const result = await getObjectFilePath(feature, testPlanningRoot); expect(result).toBe( join(testPlanningRoot, "f", "F-test-feature", "F-test-feature.md"), ); }); it("should return correct path for feature under epic", async () => { const feature = createMockObject( "F-test-feature", TrellisObjectType.FEATURE, "E-test-epic", ); const mockEpic = createMockObject( "E-test-epic", TrellisObjectType.EPIC, "P-test-project", ); mockGetObjectById.mockResolvedValueOnce(mockEpic); const result = await getObjectFilePath(feature, testPlanningRoot); expect(result).toBe( join( testPlanningRoot, "p", "P-test-project", "e", "E-test-epic", "f", "F-test-feature", "F-test-feature.md", ), ); expect(mockGetObjectById).toHaveBeenCalledWith( "E-test-epic", testPlanningRoot, ); }); it("should return correct path for feature under standalone epic", async () => { const feature = createMockObject( "F-test-feature", TrellisObjectType.FEATURE, "E-test-epic", ); const mockEpic = createMockObject("E-test-epic", TrellisObjectType.EPIC); // No parent mockGetObjectById.mockResolvedValueOnce(mockEpic); const result = await getObjectFilePath(feature, testPlanningRoot); expect(result).toBe( join( testPlanningRoot, "e", "E-test-epic", "f", "F-test-feature", "F-test-feature.md", ), ); }); it("should throw error when feature parent is not epic", async () => { const feature = createMockObject( "F-test-feature", TrellisObjectType.FEATURE, "P-test-project", ); const mockProject = createMockObject( "P-test-project", TrellisObjectType.PROJECT, ); mockGetObjectById.mockResolvedValueOnce(mockProject); await expect( getObjectFilePath(feature, testPlanningRoot), ).rejects.toThrow("Feature F-test-feature parent must be an epic"); }); }); describe("Task objects", () => { it("should return correct path for standalone task with open status", async () => { const task = createMockObject( "T-test-task", TrellisObjectType.TASK, undefined, TrellisObjectStatus.OPEN, ); const result = await getObjectFilePath(task, testPlanningRoot); expect(result).toBe( join(testPlanningRoot, "t", "open", "T-test-task.md"), ); }); it("should return correct path for standalone task with closed status", async () => { const task = createMockObject( "T-test-task", TrellisObjectType.TASK, undefined, TrellisObjectStatus.DONE, ); const result = await getObjectFilePath(task, testPlanningRoot); expect(result).toBe( join(testPlanningRoot, "t", "closed", "T-test-task.md"), ); }); it("should return correct path for standalone task with wont-do status", async () => { const task = createMockObject( "T-test-task", TrellisObjectType.TASK, undefined, TrellisObjectStatus.WONT_DO, ); const result = await getObjectFilePath(task, testPlanningRoot); expect(result).toBe( join(testPlanningRoot, "t", "closed", "T-test-task.md"), ); }); it("should return correct path for task under standalone feature", async () => { const task = createMockObject( "T-test-task", TrellisObjectType.TASK, "F-test-feature", TrellisObjectStatus.OPEN, ); const mockFeature = createMockObject( "F-test-feature", TrellisObjectType.FEATURE, ); // No parent mockGetObjectById.mockResolvedValueOnce(mockFeature); const result = await getObjectFilePath(task, testPlanningRoot); expect(result).toBe( join( testPlanningRoot, "f", "F-test-feature", "t", "open", "T-test-task.md", ), ); }); it("should return correct path for task under feature in project hierarchy", async () => { const task = createMockObject( "T-test-task", TrellisObjectType.TASK, "F-test-feature", TrellisObjectStatus.IN_PROGRESS, ); const mockFeature = createMockObject( "F-test-feature", TrellisObjectType.FEATURE, "E-test-epic", ); const mockEpic = createMockObject( "E-test-epic", TrellisObjectType.EPIC, "P-test-project", ); mockGetObjectById.mockResolvedValueOnce(mockFeature); mockGetObjectById.mockResolvedValueOnce(mockEpic); const result = await getObjectFilePath(task, testPlanningRoot); expect(result).toBe( join( testPlanningRoot, "p", "P-test-project", "e", "E-test-epic", "f", "F-test-feature", "t", "open", "T-test-task.md", ), ); }); it("should throw error when task parent is not feature", async () => { const task = createMockObject( "T-test-task", TrellisObjectType.TASK, "E-test-epic", ); const mockEpic = createMockObject( "E-test-epic", TrellisObjectType.EPIC, "P-test-project", ); mockGetObjectById.mockResolvedValueOnce(mockEpic); await expect(getObjectFilePath(task, testPlanningRoot)).rejects.toThrow( "Task T-test-task parent must be a feature", ); }); it("should throw error when feature parent is not epic", async () => { const task = createMockObject( "T-test-task", TrellisObjectType.TASK, "F-test-feature", ); const mockFeature = createMockObject( "F-test-feature", TrellisObjectType.FEATURE, "E-test-epic", ); const mockProject = createMockObject( "P-test-project", TrellisObjectType.PROJECT, ); // Wrong type mockGetObjectById.mockResolvedValueOnce(mockFeature); mockGetObjectById.mockResolvedValueOnce(mockProject); await expect(getObjectFilePath(task, testPlanningRoot)).rejects.toThrow( "Feature parent E-test-epic must be an epic", ); }); it("should return correct path for task under feature under standalone epic", async () => { const task = createMockObject( "T-test-task", TrellisObjectType.TASK, "F-test-feature", ); const mockFeature = createMockObject( "F-test-feature", TrellisObjectType.FEATURE, "E-test-epic", ); const mockEpic = createMockObject("E-test-epic", TrellisObjectType.EPIC); // No parent mockGetObjectById.mockResolvedValueOnce(mockFeature); mockGetObjectById.mockResolvedValueOnce(mockEpic); const result = await getObjectFilePath(task, testPlanningRoot); expect(result).toBe( join( testPlanningRoot, "e", "E-test-epic", "f", "F-test-feature", "t", "open", "T-test-task.md", ), ); }); }); describe("Unknown object type", () => { it("should throw error for unknown object type", async () => { const unknownObject = { ...createMockObject("X-unknown", TrellisObjectType.PROJECT), type: "unknown" as any, }; await expect( getObjectFilePath(unknownObject, testPlanningRoot), ).rejects.toThrow("Unknown object type: unknown"); }); }); });

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/langadventurellc/task-trellis-mcp'

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