test-utilities.tsβ’5.79 kB
import { test } from "node:test";
import assert from "node:assert";
import { setTimeout } from "node:timers/promises";
// Test helper to simulate tool calls
interface ToolCallResult {
  content: Array<{ type: string; text: string }>;
}
async function simulateToolCall(toolName: string, args: any): Promise<any> {
  // This would be replaced with actual MCP client calls in production
  const result = { content: [{ type: "text", text: JSON.stringify(args) }] };
  return JSON.parse(result.content[0].text);
}
test("Cache operations", async (t) => {
  await t.test("should store and retrieve values", async () => {
    // Store a value
    const putResult = await simulateToolCall("cache_put", {
      key: "test-key",
      value: { name: "test", count: 42 },
      ttl_seconds: 60
    });
    
    assert.strictEqual(putResult.key, "test-key");
    assert.strictEqual(putResult.ttl_seconds, 60);
    
    // Retrieve the value
    const getResult = await simulateToolCall("cache_get", {
      key: "test-key"
    });
    
    assert.strictEqual(getResult.key, "test-key");
    assert.deepStrictEqual(getResult.value, { name: "test", count: 42 });
  });
  await t.test("should handle cache misses", async () => {
    const result = await simulateToolCall("cache_get", {
      key: "non-existent-key"
    });
    
    assert.strictEqual(result.found, false);
  });
  await t.test("should support namespaces", async () => {
    // Store in different namespaces
    await simulateToolCall("cache_put", {
      key: "same-key",
      value: "namespace1-value",
      namespace: "ns1"
    });
    
    await simulateToolCall("cache_put", {
      key: "same-key",
      value: "namespace2-value",
      namespace: "ns2"
    });
    
    // Retrieve from specific namespaces
    const ns1Result = await simulateToolCall("cache_get", {
      key: "same-key",
      namespace: "ns1"
    });
    
    const ns2Result = await simulateToolCall("cache_get", {
      key: "same-key",
      namespace: "ns2"
    });
    
    assert.strictEqual(ns1Result.value, "namespace1-value");
    assert.strictEqual(ns2Result.value, "namespace2-value");
  });
});
test("Retry operations", async (t) => {
  await t.test("should track retry attempts", async () => {
    const operationId = "test-retry-" + Date.now();
    
    // First attempt
    const attempt1 = await simulateToolCall("retry_operation", {
      operation_id: operationId,
      operation_type: "http_request",
      operation_data: { url: "https://example.com" },
      max_retries: 3
    });
    
    assert.strictEqual(attempt1.operation_id, operationId);
    assert.strictEqual(attempt1.operation_type, "http_request");
  });
  await t.test("should respect max retries", async () => {
    const operationId = "test-max-retries-" + Date.now();
    
    // Simulate multiple failed attempts
    for (let i = 0; i < 5; i++) {
      const result = await simulateToolCall("retry_operation", {
        operation_id: operationId,
        operation_type: "test",
        operation_data: {},
        max_retries: 3
      });
      
      if (i >= 3) {
        assert.strictEqual(result.status, "max_retries_exceeded");
      }
    }
  });
});
test("Batch operations", async (t) => {
  await t.test("should process operations with concurrency control", async () => {
    const operations = Array.from({ length: 10 }, (_, i) => ({
      id: `op-${i}`,
      type: "test",
      data: { index: i }
    }));
    
    const result = await simulateToolCall("batch_operation", {
      operations,
      concurrency: 3,
      timeout_ms: 5000
    });
    
    assert.strictEqual(result.operations.length, 10);
    assert.strictEqual(result.concurrency, 3);
  });
  await t.test("should handle operation failures", async () => {
    const operations = [
      { id: "success-1", type: "test", data: { shouldFail: false } },
      { id: "fail-1", type: "test", data: { shouldFail: true } },
      { id: "success-2", type: "test", data: { shouldFail: false } }
    ];
    
    const result = await simulateToolCall("batch_operation", {
      operations,
      continue_on_error: true
    });
    
    assert.strictEqual(result.operations.length, 3);
    assert.strictEqual(result.continue_on_error, true);
  });
});
test("Rate limiting", async (t) => {
  await t.test("should track and limit requests", async () => {
    const resource = "test-api-" + Date.now();
    
    // Make requests up to the limit
    for (let i = 0; i < 5; i++) {
      const result = await simulateToolCall("rate_limit_check", {
        resource,
        max_requests: 5,
        window_seconds: 60,
        increment: true
      });
      
      assert.strictEqual(result.allowed, true);
      assert.strictEqual(result.remaining, 4 - i);
    }
    
    // Next request should be blocked
    const blockedResult = await simulateToolCall("rate_limit_check", {
      resource,
      max_requests: 5,
      window_seconds: 60,
      increment: true
    });
    
    assert.strictEqual(blockedResult.allowed, false);
    assert.strictEqual(blockedResult.remaining, 0);
  });
  await t.test("should reset after time window", async () => {
    const resource = "test-reset-" + Date.now();
    
    // Use a very short window for testing
    const result1 = await simulateToolCall("rate_limit_check", {
      resource,
      max_requests: 1,
      window_seconds: 1,
      increment: true
    });
    
    assert.strictEqual(result1.allowed, true);
    
    // Wait for window to expire
    await setTimeout(1100);
    
    const result2 = await simulateToolCall("rate_limit_check", {
      resource,
      max_requests: 1,
      window_seconds: 1,
      increment: true
    });
    
    assert.strictEqual(result2.allowed, true);
  });
});
console.log("All tests completed!");