Skip to main content
Glama

Perplexity MCP Server

database.test.ts8.11 kB
import { existsSync, mkdirSync } from "node:fs"; import { join } from "node:path"; import { beforeEach, describe, expect, it, vi } from "vitest"; import type { ChatMessage } from "../../types/index.js"; import { DatabaseManager } from "../../server/modules/DatabaseManager.js"; // Mock Node.js fs module vi.mock("node:fs", () => ({ existsSync: vi.fn(), mkdirSync: vi.fn(), })); // Mock Node.js path module const { mockDirname } = vi.hoisted(() => ({ mockDirname: vi.fn(), })); vi.mock("node:path", () => ({ dirname: mockDirname, join: vi.fn(), })); // Mock Node.js url module vi.mock("node:url", () => ({ fileURLToPath: vi.fn().mockReturnValue("/mock/path/to/module.js"), })); // Mock bun:sqlite vi.mock("bun:sqlite", () => { const mockStmt = { all: vi.fn(), run: vi.fn(), }; return { Database: vi.fn().mockImplementation(() => ({ close: vi.fn(), exec: vi.fn(), prepare: vi.fn().mockReturnValue(mockStmt), query: vi.fn().mockReturnValue(mockStmt), })), }; }); // Mock database utilities vi.mock("../../utils/db.js", () => ({ initializeDatabase: vi.fn(), getChatHistory: vi.fn(), saveChatMessage: vi.fn(), })); // Mock logging vi.mock("../../utils/logging.js", () => ({ logInfo: vi.fn(), logWarn: vi.fn(), logError: vi.fn(), })); import * as dbUtils from "../../utils/db.js"; import * as logging from "../../utils/logging.js"; const mockExistsSync = vi.mocked(existsSync); const mockMkdirSync = vi.mocked(mkdirSync); const mockJoin = vi.mocked(join); const mockInitializeDatabase = vi.mocked(dbUtils.initializeDatabase); const mockGetChatHistory = vi.mocked(dbUtils.getChatHistory); const mockSaveChatMessage = vi.mocked(dbUtils.saveChatMessage); const mockLogInfo = vi.mocked(logging.logInfo); const mockLogError = vi.mocked(logging.logError); describe("DatabaseManager", () => { let databaseManager: DatabaseManager; beforeEach(() => { vi.clearAllMocks(); databaseManager = new DatabaseManager(); }); describe("constructor", () => { it("should create instance with default path", () => { const manager = new DatabaseManager(); expect(manager).toBeInstanceOf(DatabaseManager); }); it("should create instance with custom path", () => { const customPath = "/custom/path/to/db.sqlite"; const manager = new DatabaseManager(customPath); expect(manager).toBeInstanceOf(DatabaseManager); }); }); describe("initialize", () => { beforeEach(() => { mockJoin.mockReturnValue("/mock/path/to/chat_history.db"); mockExistsSync.mockReturnValue(true); mockInitializeDatabase.mockImplementation(() => {}); }); it("should initialize successfully with existing directory", () => { mockExistsSync.mockReturnValue(true); databaseManager.initialize(); expect(mockJoin).toHaveBeenCalled(); expect(mockInitializeDatabase).toHaveBeenCalled(); expect(mockLogInfo).toHaveBeenCalledWith("DatabaseManager initialized successfully"); expect(databaseManager.isInitialized()).toBe(true); }); it("should create directory if it doesn't exist", () => { mockExistsSync.mockReturnValue(false); const mockDirPath = "/mock/path/to"; mockDirname.mockReturnValue(mockDirPath); databaseManager.initialize(); expect(mockMkdirSync).toHaveBeenCalledWith(mockDirPath, { recursive: true }); expect(mockLogInfo).toHaveBeenCalledWith(`Created database directory: ${mockDirPath}`); }); it("should use custom database path when provided", () => { const customPath = "/custom/db/path.sqlite"; const customManager = new DatabaseManager(customPath); expect(customManager).toBeInstanceOf(DatabaseManager); }); it("should handle initialization errors", () => { const error = new Error("Database initialization failed"); mockInitializeDatabase.mockImplementationOnce(() => { throw error; }); expect(() => databaseManager.initialize()).toThrow("Database initialization failed"); expect(mockLogError).toHaveBeenCalledWith( "DatabaseManager initialization failed:", expect.any(Object), ); }); }); describe("getChatHistory", () => { beforeEach(() => { // Initialize the database manager mockJoin.mockReturnValue("/mock/path/to/chat_history.db"); mockExistsSync.mockReturnValue(true); mockInitializeDatabase.mockImplementation(() => {}); databaseManager.initialize(); }); it("should get chat history successfully", () => { const chatId = "test-chat-123"; const mockMessages: ChatMessage[] = [ { role: "user", content: "Hello" }, { role: "assistant", content: "Hi there!" }, ]; mockGetChatHistory.mockReturnValue(mockMessages); const result = databaseManager.getChatHistory(chatId); expect(result).toEqual(mockMessages); expect(mockGetChatHistory).toHaveBeenCalledWith(expect.anything(), chatId); }); it("should throw error when not initialized", () => { const uninitializedManager = new DatabaseManager(); expect(() => uninitializedManager.getChatHistory("test-chat")).toThrow( "Database not initialized", ); }); it("should throw error when chat ID is not provided", () => { expect(() => databaseManager.getChatHistory("")).toThrow("Chat ID is required"); }); }); describe("saveChatMessage", () => { beforeEach(() => { // Initialize the database manager mockJoin.mockReturnValue("/mock/path/to/chat_history.db"); mockExistsSync.mockReturnValue(true); mockInitializeDatabase.mockImplementation(() => {}); databaseManager.initialize(); }); it("should save user message successfully", () => { const chatId = "test-chat-123"; const role = "user"; const content = "Hello, how are you?"; databaseManager.saveChatMessage(chatId, role, content); expect(mockSaveChatMessage).toHaveBeenCalledWith(expect.anything(), chatId, { role, content, }); expect(mockLogInfo).toHaveBeenCalledWith(`Saved ${role} message for chat ${chatId}`); }); it("should save assistant message successfully", () => { const chatId = "test-chat-456"; const role = "assistant"; const content = "I'm doing well, thank you!"; databaseManager.saveChatMessage(chatId, role, content); expect(mockSaveChatMessage).toHaveBeenCalledWith(expect.anything(), chatId, { role, content, }); expect(mockLogInfo).toHaveBeenCalledWith(`Saved ${role} message for chat ${chatId}`); }); it("should throw error when not initialized", () => { const uninitializedManager = new DatabaseManager(); expect(() => uninitializedManager.saveChatMessage("chat", "user", "message")).toThrow( "Database not initialized", ); }); }); describe("close", () => { it("should close database connection successfully", () => { // Initialize first mockJoin.mockReturnValue("/mock/path/to/chat_history.db"); mockExistsSync.mockReturnValue(true); mockInitializeDatabase.mockImplementation(() => {}); databaseManager.initialize(); databaseManager.close(); expect(mockLogInfo).toHaveBeenCalledWith("Database connection closed successfully"); expect(databaseManager.isInitialized()).toBe(false); }); it("should handle close when not initialized", () => { databaseManager.close(); // Should not throw error }); }); describe("isInitialized", () => { it("should return false when not initialized", () => { expect(databaseManager.isInitialized()).toBe(false); }); it("should return true when properly initialized", () => { mockJoin.mockReturnValue("/mock/path/to/chat_history.db"); mockExistsSync.mockReturnValue(true); mockInitializeDatabase.mockImplementation(() => {}); databaseManager.initialize(); expect(databaseManager.isInitialized()).toBe(true); }); }); });

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/wysh3/perplexity-mcp-zerver'

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