Skip to main content
Glama

WebDAV MCP Server

by masx200
directory-tree.test.ts5.85 kB
import { afterEach, beforeEach, describe, expect, it } from "@jest/globals"; import * as fs from "fs/promises"; import * as path from "path"; import * as os from "os"; // We need to test the buildTree function, but it's defined inside the request handler // So we'll extract the core logic into a testable function import { minimatch } from "minimatch"; interface TreeEntry { name: string; type: "file" | "directory"; children?: TreeEntry[]; } async function buildTreeForTesting( currentPath: string, rootPath: string, excludePatterns: string[] = [], ): Promise<TreeEntry[]> { const entries = await fs.readdir(currentPath, { withFileTypes: true }); const result: TreeEntry[] = []; for (const entry of entries) { const relativePath = path.relative( rootPath, path.join(currentPath, entry.name), ); const shouldExclude = excludePatterns.some((pattern) => { if (pattern.includes("*")) { return minimatch(relativePath, pattern, { dot: true }); } // For files: match exact name or as part of path // For directories: match as directory path return minimatch(relativePath, pattern, { dot: true }) || minimatch(relativePath, `**/${pattern}`, { dot: true }) || minimatch(relativePath, `**/${pattern}/**`, { dot: true }); }); if (shouldExclude) { continue; } const entryData: TreeEntry = { name: entry.name, type: entry.isDirectory() ? "directory" : "file", }; if (entry.isDirectory()) { const subPath = path.join(currentPath, entry.name); entryData.children = await buildTreeForTesting( subPath, rootPath, excludePatterns, ); } result.push(entryData); } return result; } describe("buildTree exclude patterns", () => { let testDir: string; beforeEach(async () => { testDir = await fs.mkdtemp(path.join(os.tmpdir(), "filesystem-test-")); // Create test directory structure await fs.mkdir(path.join(testDir, "src")); await fs.mkdir(path.join(testDir, "node_modules")); await fs.mkdir(path.join(testDir, ".git")); await fs.mkdir(path.join(testDir, "nested", "node_modules"), { recursive: true, }); // Create test files await fs.writeFile(path.join(testDir, ".env"), "SECRET=value"); await fs.writeFile(path.join(testDir, ".env.local"), "LOCAL_SECRET=value"); await fs.writeFile( path.join(testDir, "src", "index.js"), 'console.log("hello");', ); await fs.writeFile(path.join(testDir, "package.json"), "{}"); await fs.writeFile( path.join(testDir, "node_modules", "module.js"), "module.exports = {};", ); await fs.writeFile( path.join(testDir, "nested", "node_modules", "deep.js"), "module.exports = {};", ); }); afterEach(async () => { await fs.rm(testDir, { recursive: true, force: true }); }); it("should exclude files matching simple patterns", async () => { // Test the current implementation - this will fail until the bug is fixed const tree = await buildTreeForTesting(testDir, testDir, [".env"]); const fileNames = tree.map((entry) => entry.name); expect(fileNames).not.toContain(".env"); expect(fileNames).toContain(".env.local"); // Should not exclude this expect(fileNames).toContain("src"); expect(fileNames).toContain("package.json"); }); it("should exclude directories matching simple patterns", async () => { const tree = await buildTreeForTesting(testDir, testDir, ["node_modules"]); const dirNames = tree.map((entry) => entry.name); expect(dirNames).not.toContain("node_modules"); expect(dirNames).toContain("src"); expect(dirNames).toContain(".git"); }); it("should exclude nested directories with same pattern", async () => { const tree = await buildTreeForTesting(testDir, testDir, ["node_modules"]); // Find the nested directory const nestedDir = tree.find((entry) => entry.name === "nested"); expect(nestedDir).toBeDefined(); expect(nestedDir!.children).toBeDefined(); // The nested/node_modules should also be excluded const nestedChildren = nestedDir!.children!.map((child) => child.name); expect(nestedChildren).not.toContain("node_modules"); }); it("should handle glob patterns correctly", async () => { const tree = await buildTreeForTesting(testDir, testDir, ["*.env"]); const fileNames = tree.map((entry) => entry.name); expect(fileNames).not.toContain(".env"); expect(fileNames).toContain(".env.local"); // *.env should not match .env.local expect(fileNames).toContain("src"); }); it("should handle dot files correctly", async () => { const tree = await buildTreeForTesting(testDir, testDir, [".git"]); const dirNames = tree.map((entry) => entry.name); expect(dirNames).not.toContain(".git"); expect(dirNames).toContain(".env"); // Should not exclude this }); it("should work with multiple exclude patterns", async () => { const tree = await buildTreeForTesting(testDir, testDir, [ "node_modules", ".env", ".git", ]); const entryNames = tree.map((entry) => entry.name); expect(entryNames).not.toContain("node_modules"); expect(entryNames).not.toContain(".env"); expect(entryNames).not.toContain(".git"); expect(entryNames).toContain("src"); expect(entryNames).toContain("package.json"); }); it("should handle empty exclude patterns", async () => { const tree = await buildTreeForTesting(testDir, testDir, []); const entryNames = tree.map((entry) => entry.name); // All entries should be included expect(entryNames).toContain("node_modules"); expect(entryNames).toContain(".env"); expect(entryNames).toContain(".git"); expect(entryNames).toContain("src"); }); });

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/masx200/mcp-webdav-server'

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