Skip to main content
Glama

docs-mcp-server

ListJobsTool.test.ts5.63 kB
import { beforeEach, describe, expect, it, type Mock, vi } from "vitest"; import type { PipelineManager } from "../pipeline/PipelineManager"; import { type PipelineJob, PipelineJobStatus } from "../pipeline/types"; import type { ScraperProgress } from "../scraper/types"; import { VersionStatus } from "../store/types"; import { ListJobsTool } from "./ListJobsTool"; // Mock dependencies vi.mock("../pipeline/PipelineManager"); vi.mock("../utils/logger"); describe("ListJobsTool", () => { // Define the mock instance directly let mockManagerInstance: Partial<PipelineManager>; let listJobsTool: ListJobsTool; // Define more complete mock data with enhanced PipelineJob interface const mockJobs: PipelineJob[] = [ { id: "job-1", library: "lib-a", version: "1.0.0", status: PipelineJobStatus.QUEUED, createdAt: new Date("2023-01-01T10:00:00Z"), progress: null, error: null, startedAt: null, finishedAt: null, // Database fields versionId: 1, versionStatus: VersionStatus.QUEUED, progressPages: 0, progressMaxPages: 0, errorMessage: null, updatedAt: new Date("2023-01-01T10:00:00Z"), sourceUrl: "url1", scraperOptions: null, }, { id: "job-2", library: "lib-b", version: "2.0.0", status: PipelineJobStatus.RUNNING, createdAt: new Date("2023-01-01T11:00:00Z"), startedAt: new Date("2023-01-01T11:05:00Z"), progress: { pagesScraped: 5, totalPages: 100, currentUrl: "url2/page5", depth: 1, maxDepth: 3, } as ScraperProgress, error: null, finishedAt: null, // Database fields versionId: 2, versionStatus: VersionStatus.RUNNING, progressPages: 5, progressMaxPages: 100, errorMessage: null, updatedAt: new Date("2023-01-01T11:05:00Z"), sourceUrl: "url2", scraperOptions: { maxDepth: 3 }, }, { id: "job-3", library: "lib-a", version: "1.1.0", status: PipelineJobStatus.COMPLETED, createdAt: new Date("2023-01-01T12:00:00Z"), startedAt: new Date("2023-01-01T12:05:00Z"), finishedAt: new Date("2023-01-01T12:15:00Z"), progress: { pagesScraped: 10, totalPages: 10, currentUrl: "url3/page10", depth: 2, maxDepth: 2, } as ScraperProgress, error: null, // Database fields versionId: 3, versionStatus: VersionStatus.COMPLETED, progressPages: 10, progressMaxPages: 10, errorMessage: null, updatedAt: new Date("2023-01-01T12:15:00Z"), sourceUrl: "url3", scraperOptions: { maxDepth: 2 }, }, ]; beforeEach(() => { vi.resetAllMocks(); // Define the mock implementation for the manager instance mockManagerInstance = { getJobs: vi.fn().mockResolvedValue(mockJobs), // Default mock returns all jobs }; // Instantiate the tool with the correctly typed mock instance listJobsTool = new ListJobsTool(mockManagerInstance as PipelineManager); }); it("should call manager.getJobs without status when no status is provided", async () => { await listJobsTool.execute({}); // Check if getJobs was called without arguments or with undefined expect(mockManagerInstance.getJobs).toHaveBeenCalledWith(undefined); }); it("should call manager.getJobs with the specified status", async () => { const targetStatus = PipelineJobStatus.RUNNING; await listJobsTool.execute({ status: targetStatus }); expect(mockManagerInstance.getJobs).toHaveBeenCalledWith(targetStatus); }); it("should return the list of jobs received from the manager", async () => { const result = await listJobsTool.execute({}); expect(result.jobs.length).toBe(mockJobs.length); expect(result.jobs.map((job) => job.id)).toEqual(mockJobs.map((job) => job.id)); // Check properties of the first simplified JobInfo object if (result.jobs.length > 0 && mockJobs.length > 0) { const firstResultJob = result.jobs[0]; const firstMockJob = mockJobs[0]; expect(firstResultJob.id).toBe(firstMockJob.id); expect(firstResultJob.library).toBe(firstMockJob.library); expect(firstResultJob.version).toBe(firstMockJob.version); expect(firstResultJob.status).toBe(firstMockJob.status); expect(firstResultJob.createdAt).toBe(firstMockJob.createdAt.toISOString()); expect(firstResultJob.startedAt).toBeNull(); // Based on first mockJob expect(firstResultJob.finishedAt).toBeNull(); // Based on first mockJob expect(firstResultJob.error).toBeNull(); // Based on first mockJob } }); it("should return a filtered list if manager returns filtered jobs", async () => { const runningJobs = mockJobs.filter( (job) => job.status === PipelineJobStatus.RUNNING, ); // Configure the mock for this specific test case (mockManagerInstance.getJobs as Mock).mockResolvedValue(runningJobs); const result = await listJobsTool.execute({ status: PipelineJobStatus.RUNNING }); expect(result.jobs.length).toBe(runningJobs.length); expect(result.jobs.map((job) => job.id)).toEqual(runningJobs.map((job) => job.id)); expect(mockManagerInstance.getJobs).toHaveBeenCalledWith(PipelineJobStatus.RUNNING); }); it("should return an empty list if manager returns an empty list", async () => { (mockManagerInstance.getJobs as Mock).mockResolvedValue([]); // Manager returns empty const result = await listJobsTool.execute({}); expect(result.jobs).toEqual([]); }); });

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/arabold/docs-mcp-server'

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