Skip to main content
Glama
track-documentation-freshness.test.ts19.3 kB
/** * Integration Tests for track_documentation_freshness Tool */ import { describe, it, expect, beforeEach, afterEach } from "@jest/globals"; import fs from "fs/promises"; import path from "path"; import os from "os"; import { trackDocumentationFreshness, type TrackDocumentationFreshnessInput, } from "../../src/tools/track-documentation-freshness.js"; // Example git SHA for testing const SHA_EXAMPLE = "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0"; describe("track_documentation_freshness Tool", () => { let tempDir: string; beforeEach(async () => { tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "track-freshness-test-")); }); afterEach(async () => { await fs.rm(tempDir, { recursive: true, force: true }); }); describe("Basic Functionality", () => { it("should track freshness with preset thresholds", async () => { const docsPath = path.join(tempDir, "docs"); await fs.mkdir(docsPath); // Create test files const now = Date.now(); await fs.writeFile( path.join(docsPath, "fresh.md"), `--- documcp: last_updated: "${new Date(now - 1 * 24 * 60 * 60 * 1000).toISOString()}" --- # Fresh Doc`, ); await fs.writeFile( path.join(docsPath, "old.md"), `--- documcp: last_updated: "${new Date(now - 60 * 24 * 60 * 60 * 1000).toISOString()}" --- # Old Doc`, ); const input: TrackDocumentationFreshnessInput = { docsPath, preset: "monthly", }; const result = await trackDocumentationFreshness(input); expect(result.success).toBe(true); expect(result.data).toBeDefined(); expect(result.data.report.totalFiles).toBe(2); expect(result.data.report.freshFiles).toBeGreaterThan(0); expect(result.metadata.executionTime).toBeGreaterThan(0); }); it("should track freshness with custom thresholds", async () => { const docsPath = path.join(tempDir, "docs"); await fs.mkdir(docsPath); await fs.writeFile( path.join(docsPath, "test.md"), `--- documcp: last_updated: "${new Date(Date.now() - 45 * 60 * 1000).toISOString()}" --- # Test`, ); const input: TrackDocumentationFreshnessInput = { docsPath, warningThreshold: { value: 30, unit: "minutes" }, staleThreshold: { value: 1, unit: "hours" }, criticalThreshold: { value: 2, unit: "hours" }, }; const result = await trackDocumentationFreshness(input); expect(result.success).toBe(true); expect(result.data.report).toBeDefined(); expect(result.data.thresholds.warning).toEqual({ value: 30, unit: "minutes", }); }); it("should identify files without metadata", async () => { const docsPath = path.join(tempDir, "docs"); await fs.mkdir(docsPath); await fs.writeFile( path.join(docsPath, "no-metadata.md"), "# No Metadata", ); const input: TrackDocumentationFreshnessInput = { docsPath, preset: "monthly", }; const result = await trackDocumentationFreshness(input); expect(result.success).toBe(true); expect(result.data.report.filesWithoutMetadata).toBe(1); expect(result.data.report.totalFiles).toBe(1); }); }); describe("Staleness Levels", () => { it("should correctly categorize fresh files", async () => { const docsPath = path.join(tempDir, "docs"); await fs.mkdir(docsPath); await fs.writeFile( path.join(docsPath, "fresh.md"), `--- documcp: last_updated: "${new Date( Date.now() - 2 * 24 * 60 * 60 * 1000, ).toISOString()}" --- # Fresh`, ); const input: TrackDocumentationFreshnessInput = { docsPath, preset: "monthly", }; const result = await trackDocumentationFreshness(input); expect(result.data.report.freshFiles).toBe(1); expect(result.data.report.staleFiles).toBe(0); expect(result.data.report.criticalFiles).toBe(0); }); it("should correctly categorize stale files", async () => { const docsPath = path.join(tempDir, "docs"); await fs.mkdir(docsPath); await fs.writeFile( path.join(docsPath, "stale.md"), `--- documcp: last_updated: "${new Date( Date.now() - 70 * 24 * 60 * 60 * 1000, ).toISOString()}" --- # Stale`, ); const input: TrackDocumentationFreshnessInput = { docsPath, preset: "monthly", }; const result = await trackDocumentationFreshness(input); expect(result.data.report.staleFiles).toBeGreaterThan(0); }); it("should correctly categorize critical files", async () => { const docsPath = path.join(tempDir, "docs"); await fs.mkdir(docsPath); await fs.writeFile( path.join(docsPath, "critical.md"), `--- documcp: last_updated: "${new Date( Date.now() - 100 * 24 * 60 * 60 * 1000, ).toISOString()}" --- # Critical`, ); const input: TrackDocumentationFreshnessInput = { docsPath, preset: "monthly", }; const result = await trackDocumentationFreshness(input); expect(result.data.report.criticalFiles).toBe(1); }); }); describe("File Listing Options", () => { it("should include file list when requested", async () => { const docsPath = path.join(tempDir, "docs"); await fs.mkdir(docsPath); await fs.writeFile(path.join(docsPath, "test.md"), "# Test"); const input: TrackDocumentationFreshnessInput = { docsPath, preset: "monthly", includeFileList: true, }; const result = await trackDocumentationFreshness(input); expect(result.data.report.files).toBeDefined(); expect(result.data.report.files.length).toBe(1); expect(result.data.formattedReport).toContain("File Details"); }); it("should exclude file list when not requested", async () => { const docsPath = path.join(tempDir, "docs"); await fs.mkdir(docsPath); await fs.writeFile(path.join(docsPath, "test.md"), "# Test"); const input: TrackDocumentationFreshnessInput = { docsPath, preset: "monthly", includeFileList: false, }; const result = await trackDocumentationFreshness(input); expect(result.data.formattedReport).not.toContain("File Details"); }); }); describe("Sorting Options", () => { it("should sort files by staleness", async () => { const docsPath = path.join(tempDir, "docs"); await fs.mkdir(docsPath); const now = Date.now(); await fs.writeFile( path.join(docsPath, "fresh.md"), `--- documcp: last_updated: "${new Date(now - 1 * 24 * 60 * 60 * 1000).toISOString()}" --- # Fresh`, ); await fs.writeFile( path.join(docsPath, "stale.md"), `--- documcp: last_updated: "${new Date(now - 60 * 24 * 60 * 60 * 1000).toISOString()}" --- # Stale`, ); const input: TrackDocumentationFreshnessInput = { docsPath, preset: "monthly", sortBy: "staleness", }; const result = await trackDocumentationFreshness(input); expect(result.success).toBe(true); // Stale files should appear first when sorted by staleness const formattedReport = result.data.formattedReport; const staleIndex = formattedReport.indexOf("stale.md"); const freshIndex = formattedReport.indexOf("fresh.md"); if (staleIndex !== -1 && freshIndex !== -1) { expect(staleIndex).toBeLessThan(freshIndex); } }); it("should sort files by age", async () => { const docsPath = path.join(tempDir, "docs"); await fs.mkdir(docsPath); const now = Date.now(); await fs.writeFile( path.join(docsPath, "newer.md"), `--- documcp: last_updated: "${new Date(now - 10 * 24 * 60 * 60 * 1000).toISOString()}" --- # Newer`, ); await fs.writeFile( path.join(docsPath, "older.md"), `--- documcp: last_updated: "${new Date(now - 50 * 24 * 60 * 60 * 1000).toISOString()}" --- # Older`, ); const input: TrackDocumentationFreshnessInput = { docsPath, preset: "monthly", sortBy: "age", }; const result = await trackDocumentationFreshness(input); expect(result.success).toBe(true); }); }); describe("Nested Directories", () => { it("should scan nested directories recursively", async () => { const docsPath = path.join(tempDir, "docs"); await fs.mkdir(docsPath); await fs.mkdir(path.join(docsPath, "api")); await fs.mkdir(path.join(docsPath, "guides")); await fs.writeFile(path.join(docsPath, "index.md"), "# Index"); await fs.writeFile(path.join(docsPath, "api", "endpoints.md"), "# API"); await fs.writeFile( path.join(docsPath, "guides", "tutorial.md"), "# Guide", ); const input: TrackDocumentationFreshnessInput = { docsPath, preset: "monthly", }; const result = await trackDocumentationFreshness(input); expect(result.data.report.totalFiles).toBe(3); }); it("should skip common ignored directories", async () => { const docsPath = path.join(tempDir, "docs"); await fs.mkdir(docsPath); await fs.mkdir(path.join(docsPath, "node_modules")); await fs.mkdir(path.join(docsPath, ".git")); await fs.writeFile(path.join(docsPath, "index.md"), "# Index"); await fs.writeFile( path.join(docsPath, "node_modules", "skip.md"), "# Skip", ); await fs.writeFile(path.join(docsPath, ".git", "skip.md"), "# Skip"); const input: TrackDocumentationFreshnessInput = { docsPath, preset: "monthly", }; const result = await trackDocumentationFreshness(input); expect(result.data.report.totalFiles).toBe(1); }); }); describe("Error Handling", () => { it("should handle non-existent directory", async () => { const input: TrackDocumentationFreshnessInput = { docsPath: "/nonexistent/path", preset: "monthly", }; const result = await trackDocumentationFreshness(input); expect(result.success).toBe(false); expect(result.error).toBeDefined(); expect(result.error?.code).toBe("FRESHNESS_TRACKING_FAILED"); }); it("should handle empty directory", async () => { const docsPath = path.join(tempDir, "empty-docs"); await fs.mkdir(docsPath); const input: TrackDocumentationFreshnessInput = { docsPath, preset: "monthly", }; const result = await trackDocumentationFreshness(input); expect(result.success).toBe(true); expect(result.data.report.totalFiles).toBe(0); }); }); describe("Preset Thresholds", () => { const presets: Array< keyof typeof import("../../src/utils/freshness-tracker.js").STALENESS_PRESETS > = ["realtime", "active", "recent", "weekly", "monthly", "quarterly"]; presets.forEach((preset) => { it(`should work with ${preset} preset`, async () => { const docsPath = path.join(tempDir, `docs-${preset}`); await fs.mkdir(docsPath); await fs.writeFile(path.join(docsPath, "test.md"), "# Test"); const input: TrackDocumentationFreshnessInput = { docsPath, preset, }; const result = await trackDocumentationFreshness(input); expect(result.success).toBe(true); expect(result.data.thresholds).toBeDefined(); }); }); }); describe("Output Format", () => { it("should include formatted report in response", async () => { const docsPath = path.join(tempDir, "docs"); await fs.mkdir(docsPath); await fs.writeFile(path.join(docsPath, "test.md"), "# Test"); const input: TrackDocumentationFreshnessInput = { docsPath, preset: "monthly", }; const result = await trackDocumentationFreshness(input); expect(result.data.formattedReport).toBeDefined(); expect(result.data.formattedReport).toContain( "Documentation Freshness Report", ); expect(result.data.formattedReport).toContain("Summary Statistics"); expect(result.data.formattedReport).toContain("Freshness Breakdown"); }); it("should include summary in response", async () => { const docsPath = path.join(tempDir, "docs"); await fs.mkdir(docsPath); await fs.writeFile(path.join(docsPath, "test.md"), "# Test"); const input: TrackDocumentationFreshnessInput = { docsPath, preset: "monthly", }; const result = await trackDocumentationFreshness(input); expect(result.data.summary).toBeDefined(); expect(result.data.summary).toContain("Scanned"); expect(result.data.summary).toContain("files"); }); it("should include metadata in response", async () => { const docsPath = path.join(tempDir, "docs"); await fs.mkdir(docsPath); await fs.writeFile(path.join(docsPath, "test.md"), "# Test"); const input: TrackDocumentationFreshnessInput = { docsPath, preset: "monthly", }; const result = await trackDocumentationFreshness(input); expect(result.metadata).toBeDefined(); expect(result.metadata.toolVersion).toBe("1.0.0"); expect(result.metadata.timestamp).toBeDefined(); expect(result.metadata.executionTime).toBeGreaterThanOrEqual(0); }); it("should handle KG storage disabled", async () => { const docsPath = path.join(tempDir, "docs"); const projectPath = tempDir; await fs.mkdir(docsPath); await fs.writeFile(path.join(docsPath, "test.md"), "# Test"); const input: TrackDocumentationFreshnessInput = { docsPath, projectPath, preset: "monthly", storeInKG: false, }; const result = await trackDocumentationFreshness(input); expect(result.success).toBe(true); expect(result.data.kgInsights).toBeUndefined(); }); it("should handle projectPath without KG storage", async () => { const docsPath = path.join(tempDir, "docs"); await fs.mkdir(docsPath); await fs.writeFile(path.join(docsPath, "test.md"), "# Test"); const input: TrackDocumentationFreshnessInput = { docsPath, // No projectPath provided preset: "monthly", storeInKG: true, // Won't store because projectPath is missing }; const result = await trackDocumentationFreshness(input); expect(result.success).toBe(true); }); it("should handle error gracefully", async () => { const input: TrackDocumentationFreshnessInput = { docsPath: "/nonexistent/path/that/does/not/exist", preset: "monthly", }; const result = await trackDocumentationFreshness(input); expect(result.success).toBe(false); expect(result.error).toBeDefined(); expect(result.error?.code).toBe("FRESHNESS_TRACKING_FAILED"); expect(result.metadata).toBeDefined(); }); it("should sort files by age", async () => { const docsPath = path.join(tempDir, "docs"); await fs.mkdir(docsPath); const now = Date.now(); await fs.writeFile( path.join(docsPath, "newer.md"), `--- documcp: last_updated: "${new Date(now - 1 * 24 * 60 * 60 * 1000).toISOString()}" --- # Newer`, ); await fs.writeFile( path.join(docsPath, "older.md"), `--- documcp: last_updated: "${new Date(now - 10 * 24 * 60 * 60 * 1000).toISOString()}" --- # Older`, ); const input: TrackDocumentationFreshnessInput = { docsPath, preset: "monthly", sortBy: "age", }; const result = await trackDocumentationFreshness(input); expect(result.success).toBe(true); expect(result.data.report.files.length).toBe(2); }); it("should sort files by path", async () => { const docsPath = path.join(tempDir, "docs"); await fs.mkdir(docsPath); await fs.writeFile(path.join(docsPath, "z.md"), "# Z"); await fs.writeFile(path.join(docsPath, "a.md"), "# A"); const input: TrackDocumentationFreshnessInput = { docsPath, preset: "monthly", sortBy: "path", }; const result = await trackDocumentationFreshness(input); expect(result.success).toBe(true); }); it("should display commit hash for files validated against commits", async () => { const docsPath = path.join(tempDir, "docs"); const projectPath = tempDir; await fs.mkdir(docsPath); // Create file with validated_against_commit metadata const fileContent = `--- documcp: last_updated: ${new Date().toISOString()} last_validated: ${new Date().toISOString()} validated_against_commit: ${SHA_EXAMPLE} --- # Test Document Content`; await fs.writeFile(path.join(docsPath, "test.md"), fileContent); const input: TrackDocumentationFreshnessInput = { docsPath, projectPath, preset: "monthly", includeFileList: true, }; const result = await trackDocumentationFreshness(input); expect(result.success).toBe(true); expect(result.data.formattedReport).toContain( SHA_EXAMPLE.substring(0, 7), ); }); it("should format warning recommendations correctly", async () => { const docsPath = path.join(tempDir, "docs"); const projectPath = tempDir; await fs.mkdir(docsPath); // Create a file with warning-level staleness const warnDate = new Date(); warnDate.setDate(warnDate.getDate() - 45); // 45 days ago (monthly preset: warning=30d, stale=60d, critical=90d) const fileContent = `--- documcp: last_updated: ${warnDate.toISOString()} last_validated: ${warnDate.toISOString()} --- # Test Document`; await fs.writeFile(path.join(docsPath, "warn.md"), fileContent); const input: TrackDocumentationFreshnessInput = { docsPath, projectPath, preset: "monthly", storeInKG: true, }; const result = await trackDocumentationFreshness(input); expect(result.success).toBe(true); expect(result.data.report.warningFiles).toBeGreaterThan(0); }); it("should format critical recommendations correctly", async () => { const docsPath = path.join(tempDir, "docs"); const projectPath = tempDir; await fs.mkdir(docsPath); // Create a file with critical-level staleness const criticalDate = new Date(); criticalDate.setDate(criticalDate.getDate() - 100); // 100 days ago (critical for monthly preset) const fileContent = `--- documcp: last_updated: ${criticalDate.toISOString()} last_validated: ${criticalDate.toISOString()} --- # Old Document`; await fs.writeFile(path.join(docsPath, "critical.md"), fileContent); const input: TrackDocumentationFreshnessInput = { docsPath, projectPath, preset: "monthly", storeInKG: true, }; const result = await trackDocumentationFreshness(input); expect(result.success).toBe(true); expect(result.data.report.criticalFiles).toBeGreaterThan(0); }); }); });

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/tosin2013/documcp'

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