Skip to main content
Glama

task-orchestrator-mcp

by 108yen
storage.test.ts7.8 kB
import * as fs from "fs" import { afterEach, beforeEach, describe, expect, it, vi } from "vitest" import type { Task } from "./storage" import { readTasks, writeTasks } from "./storage" // Mock the fs module vi.mock("fs", () => ({ existsSync: vi.fn(), readFileSync: vi.fn(), writeFileSync: vi.fn(), })) const mockFs = vi.mocked(fs) describe("Storage", () => { const mockTask: Task = { description: "Test Description", id: "test-id-1", name: "Test Task", status: "todo", tasks: [], // New nested structure } const mockTaskWithResolution: Task = { description: "Completed Description", id: "test-id-2", name: "Completed Task", resolution: "Task completed successfully", status: "done", tasks: [], // New nested structure } beforeEach(() => { // Clear all mocks before each test vi.clearAllMocks() // Reset environment variables delete process.env.FILE_PATH }) afterEach(() => { // Clean up environment variables delete process.env.FILE_PATH }) describe("File-based storage mode (FILE_PATH set)", () => { beforeEach(() => { process.env.FILE_PATH = "/test/path/tasks.json" }) describe("readTasks", () => { it("should read tasks from file when file exists", () => { const fileContent = JSON.stringify([mockTask, mockTaskWithResolution]) mockFs.existsSync.mockReturnValue(true) mockFs.readFileSync.mockReturnValue(fileContent) const result = readTasks() expect(mockFs.existsSync).toHaveBeenCalledWith("/test/path/tasks.json") expect(mockFs.readFileSync).toHaveBeenCalledWith( "/test/path/tasks.json", "utf-8", ) expect(result).toHaveLength(2) expect(result[0]).toEqual(mockTask) expect(result[1]).toEqual(mockTaskWithResolution) }) it("should return empty array when file does not exist", () => { mockFs.existsSync.mockReturnValue(false) const result = readTasks() expect(mockFs.existsSync).toHaveBeenCalledWith("/test/path/tasks.json") expect(mockFs.readFileSync).not.toHaveBeenCalled() expect(result).toEqual([]) }) it("should return empty array and log error when file read fails", () => { const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { // Mock implementation }) mockFs.existsSync.mockReturnValue(true) mockFs.readFileSync.mockImplementation(() => { throw new Error("File read error") }) const result = readTasks() expect(result).toEqual([]) expect(consoleSpy).toHaveBeenCalledWith( "Error reading tasks from file:", expect.any(Error), ) consoleSpy.mockRestore() }) it("should return empty array when JSON parsing fails", () => { const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { // Mock implementation }) mockFs.existsSync.mockReturnValue(true) mockFs.readFileSync.mockReturnValue("invalid json") const result = readTasks() expect(result).toEqual([]) expect(consoleSpy).toHaveBeenCalledWith( "Error reading tasks from file:", expect.any(Error), ) consoleSpy.mockRestore() }) }) describe("writeTasks", () => { it("should write tasks to file successfully", () => { const tasks = [mockTask, mockTaskWithResolution] writeTasks(tasks) expect(mockFs.writeFileSync).toHaveBeenCalledWith( "/test/path/tasks.json", JSON.stringify(tasks, null, 2), "utf-8", ) }) it("should throw error when file write fails", () => { const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { // Mock implementation }) const writeError = new Error("File write error") mockFs.writeFileSync.mockImplementation(() => { throw writeError }) expect(() => writeTasks([mockTask])).toThrow("File write error") expect(consoleSpy).toHaveBeenCalledWith( "Error writing tasks to file:", writeError, ) consoleSpy.mockRestore() }) it("should handle empty task array", () => { writeTasks([]) expect(mockFs.writeFileSync).toHaveBeenCalledWith( "/test/path/tasks.json", JSON.stringify([], null, 2), "utf-8", ) }) }) }) describe("In-memory storage mode (FILE_PATH not set)", () => { beforeEach(() => { // Ensure FILE_PATH is not set delete process.env.FILE_PATH }) describe("readTasks", () => { it("should return empty array initially", () => { const result = readTasks() expect(result).toEqual([]) expect(mockFs.existsSync).not.toHaveBeenCalled() expect(mockFs.readFileSync).not.toHaveBeenCalled() }) it("should return tasks from memory after writing", () => { const tasks = [mockTask, mockTaskWithResolution] writeTasks(tasks) const result = readTasks() expect(result).toEqual(tasks) expect(mockFs.writeFileSync).not.toHaveBeenCalled() expect(mockFs.readFileSync).not.toHaveBeenCalled() }) }) describe("writeTasks", () => { it("should store tasks in memory", () => { const tasks = [mockTask] writeTasks(tasks) const result = readTasks() expect(result).toEqual(tasks) expect(mockFs.writeFileSync).not.toHaveBeenCalled() }) it("should replace existing tasks in memory", () => { const initialTasks = [mockTask] const newTasks = [mockTaskWithResolution] writeTasks(initialTasks) expect(readTasks()).toEqual(initialTasks) writeTasks(newTasks) expect(readTasks()).toEqual(newTasks) }) it("should handle empty task array in memory mode", () => { writeTasks([mockTask]) expect(readTasks()).toEqual([mockTask]) writeTasks([]) expect(readTasks()).toEqual([]) }) it("should create a copy of tasks array to avoid mutation", () => { const tasks = [mockTask] writeTasks(tasks) tasks.push(mockTaskWithResolution) // Mutate original array const result = readTasks() expect(result).toHaveLength(1) expect(result[0]).toEqual(mockTask) }) }) }) describe("Environment variable switching", () => { it("should switch from memory to file mode when FILE_PATH is set", () => { // Start in memory mode const memoryTasks = [mockTask] writeTasks(memoryTasks) expect(readTasks()).toEqual(memoryTasks) // Switch to file mode process.env.FILE_PATH = "/test/path/tasks.json" mockFs.existsSync.mockReturnValue(false) const result = readTasks() expect(result).toEqual([]) // File mode returns empty array when file doesn't exist expect(mockFs.existsSync).toHaveBeenCalledWith("/test/path/tasks.json") }) it("should switch from file to memory mode when FILE_PATH is unset", () => { // Start in file mode process.env.FILE_PATH = "/test/path/tasks.json" const fileTasks = [mockTaskWithResolution] mockFs.existsSync.mockReturnValue(true) mockFs.readFileSync.mockReturnValue(JSON.stringify(fileTasks)) expect(readTasks()).toEqual(fileTasks) // Switch to memory mode and clear memory storage delete process.env.FILE_PATH writeTasks([]) // Clear memory storage const result = readTasks() expect(result).toEqual([]) // Memory mode starts empty after clearing }) }) })

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