Skip to main content
Glama

Analytical MCP Server

research_cache.test.ts8.1 kB
import { describe, it, expect, jest, beforeEach, afterEach } from '@jest/globals'; import { researchCache, ResearchCacheNamespace } from '../research_cache.js'; import { cacheManager } from '../cache_manager.js'; import { config } from '../config.js'; describe('ResearchCache', () => { // Mock original config const originalEnableCache = config.ENABLE_RESEARCH_CACHE; beforeEach(() => { // Enable cache for tests config.ENABLE_RESEARCH_CACHE = 'true'; // Spy on cache manager methods jest.spyOn(cacheManager, 'get'); jest.spyOn(cacheManager, 'set'); jest.spyOn(cacheManager, 'clearNamespace'); // Mock the return value of get to be null (cache miss) (cacheManager.get as jest.Mock).mockReturnValue(null); }); afterEach(() => { // Restore original config config.ENABLE_RESEARCH_CACHE = originalEnableCache; // Restore mocks jest.restoreAllMocks(); }); it('should store and retrieve search results from cache', () => { // Prepare data const query = 'test query'; const options = { numResults: 5 }; const results = { results: [{ title: 'Test', url: 'http://test.com' }] }; // Set a mock return value for the next call to cacheManager.get (cacheManager.get as jest.Mock).mockReturnValueOnce(null).mockReturnValueOnce(results); // Initial call should be a cache miss const cachedResults1 = researchCache.getSearchResults(query, options); expect(cachedResults1).toBeNull(); expect(cacheManager.get).toHaveBeenCalled(); // Store results in cache researchCache.setSearchResults(query, options, results); expect(cacheManager.set).toHaveBeenCalled(); // Next call should be a cache hit const cachedResults2 = researchCache.getSearchResults(query, options); expect(cachedResults2).toEqual(results); }); it('should store and retrieve extracted facts from cache', () => { // Prepare data const text = 'test text content'; const maxFacts = 3; const facts = ['Fact 1', 'Fact 2', 'Fact 3']; // Set a mock return value for the next call to cacheManager.get (cacheManager.get as jest.Mock).mockReturnValueOnce(null).mockReturnValueOnce(facts); // Initial call should be a cache miss const cachedFacts1 = researchCache.getExtractedFacts(text, maxFacts); expect(cachedFacts1).toBeNull(); // Store facts in cache researchCache.setExtractedFacts(text, maxFacts, facts); expect(cacheManager.set).toHaveBeenCalled(); // Next call should be a cache hit const cachedFacts2 = researchCache.getExtractedFacts(text, maxFacts); expect(cachedFacts2).toEqual(facts); }); it('should store and retrieve validation results from cache', () => { // Prepare data const context = 'validation context'; const data = [{ id: 1 }, { id: 2 }]; const results = { validatedData: [ { id: 1, valid: true }, { id: 2, valid: false }, ], researchContext: ['Context 1', 'Context 2'], }; // Set a mock return value for the next call to cacheManager.get (cacheManager.get as jest.Mock).mockReturnValueOnce(null).mockReturnValueOnce(results); // Initial call should be a cache miss const cachedResults1 = researchCache.getValidationResults(context, data); expect(cachedResults1).toBeNull(); // Store results in cache researchCache.setValidationResults(context, data, results); expect(cacheManager.set).toHaveBeenCalled(); // Next call should be a cache hit const cachedResults2 = researchCache.getValidationResults(context, data); expect(cachedResults2).toEqual(results); }); it('should store and retrieve cross-domain results from cache', () => { // Prepare data const problem = 'test problem'; const domains = ['domain1', 'domain2']; const results = { analogies: ['Analogy 1', 'Analogy 2'], potentialSolutions: ['Solution 1', 'Solution 2'], }; // Set a mock return value for the next call to cacheManager.get (cacheManager.get as jest.Mock).mockReturnValueOnce(null).mockReturnValueOnce(results); // Initial call should be a cache miss const cachedResults1 = researchCache.getCrossDomainResults(problem, domains); expect(cachedResults1).toBeNull(); // Store results in cache researchCache.setCrossDomainResults(problem, domains, results); expect(cacheManager.set).toHaveBeenCalled(); // Next call should be a cache hit const cachedResults2 = researchCache.getCrossDomainResults(problem, domains); expect(cachedResults2).toEqual(results); }); it('should store and retrieve enrichment results from cache', () => { // Prepare data const context = 'enrichment context'; const data = [{ id: 1 }, { id: 2 }]; const options = { enhancedExtraction: true }; const results = { enrichedData: [ { id: 1, enriched: true }, { id: 2, enriched: true }, ], researchInsights: ['Insight 1', 'Insight 2'], confidence: 0.85, }; // Set a mock return value for the next call to cacheManager.get (cacheManager.get as jest.Mock).mockReturnValueOnce(null).mockReturnValueOnce(results); // Initial call should be a cache miss const cachedResults1 = researchCache.getEnrichmentResults(context, data, options); expect(cachedResults1).toBeNull(); // Store results in cache researchCache.setEnrichmentResults(context, data, options, results); expect(cacheManager.set).toHaveBeenCalled(); // Next call should be a cache hit const cachedResults2 = researchCache.getEnrichmentResults(context, data, options); expect(cachedResults2).toEqual(results); }); it('should clear a specific cache namespace', () => { // Clear the search cache researchCache.clear(ResearchCacheNamespace.SEARCH); // Verify that clearNamespace was called with the correct namespace expect(cacheManager.clearNamespace).toHaveBeenCalledWith(ResearchCacheNamespace.SEARCH); }); it('should clear all research caches', () => { // Clear all caches researchCache.clearAll(); // Verify that clearNamespace was called for each namespace expect(cacheManager.clearNamespace).toHaveBeenCalledWith(ResearchCacheNamespace.SEARCH); expect(cacheManager.clearNamespace).toHaveBeenCalledWith(ResearchCacheNamespace.FACTS); expect(cacheManager.clearNamespace).toHaveBeenCalledWith(ResearchCacheNamespace.VALIDATION); expect(cacheManager.clearNamespace).toHaveBeenCalledWith(ResearchCacheNamespace.CROSS_DOMAIN); expect(cacheManager.clearNamespace).toHaveBeenCalledWith(ResearchCacheNamespace.ENRICHMENT); }); it('should not cache when caching is disabled', () => { // Disable caching config.ENABLE_RESEARCH_CACHE = 'false'; // Prepare data const query = 'test query'; const options = { numResults: 5 }; const results = { results: [{ title: 'Test', url: 'http://test.com' }] }; // Cache operations should be no-ops researchCache.setSearchResults(query, options, results); const cachedResults = researchCache.getSearchResults(query, options); // Should not interact with cache manager expect(cacheManager.set).not.toHaveBeenCalled(); expect(cachedResults).toBeNull(); }); it('should get stats for all namespaces', () => { // Mock getStats to return test stats jest.spyOn(cacheManager, 'getStats').mockImplementation((namespace) => { return { hits: 10, misses: 5, puts: 15, evictions: 2, size: 13, oldestEntry: Date.now() - 3600000, newestEntry: Date.now(), }; }); // Get stats const stats = researchCache.getStats(); // Should have stats for each namespace expect(stats).toHaveProperty(ResearchCacheNamespace.SEARCH); expect(stats).toHaveProperty(ResearchCacheNamespace.FACTS); expect(stats).toHaveProperty(ResearchCacheNamespace.VALIDATION); expect(stats).toHaveProperty(ResearchCacheNamespace.CROSS_DOMAIN); expect(stats).toHaveProperty(ResearchCacheNamespace.ENRICHMENT); }); });

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/quanticsoul4772/analytical-mcp'

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