Skip to main content
Glama
config.spec.ts10.5 kB
import { describe, it, beforeAll, afterAll, beforeEach, afterEach, jest, expect } from '@jest/globals'; import { NetworkId } from '@midnight-ntwrk/midnight-js-network-id'; // Mock path jest.mock('path', () => ({ resolve: jest.fn((a, b) => `${a}/${b}`), dirname: jest.fn((p: string) => p.replace('/file.js', '')), join: jest.fn((a, b) => `${a}/${b}`), })); // Mock url jest.mock('url', () => ({ fileURLToPath: jest.fn((url: string) => url.replace('file://', '')), })); // Mock dotenv jest.mock('dotenv', () => ({ config: jest.fn(), })); // Mock the NetworkId enum jest.mock('@midnight-ntwrk/midnight-js-network-id', () => ({ NetworkId: { TestNet: 'TestNet', MainNet: 'MainNet', Undeployed: 'Undeployed' } })); describe('Config Module', () => { const originalEnv = process.env; beforeEach(() => { jest.clearAllMocks(); jest.resetModules(); process.env = { ...originalEnv }; // Clear all relevant environment variables delete process.env.NETWORK_ID; delete process.env.WALLET_FILENAME; delete process.env.LOG_LEVEL; delete process.env.AGENT_ID; delete process.env.WALLET_BACKUP_FOLDER; delete process.env.USE_EXTERNAL_PROOF_SERVER; delete process.env.PROOF_SERVER; delete process.env.INDEXER; delete process.env.INDEXER_WS; delete process.env.MN_NODE; delete process.env.SERVER_PORT; delete process.env.WALLET_SERVER_HOST; delete process.env.WALLET_SERVER_PORT; }); afterEach(() => { process.env = originalEnv; jest.clearAllMocks(); }); describe('loadConfig function', () => { it('should throw error if AGENT_ID is not provided', async () => { await expect(async () => { const { loadConfig } = await import('../../src/config.js'); loadConfig(); }).rejects.toThrow('AGENT_ID environment variable is required'); }); it('should use default values when minimal env is provided', async () => { // Set minimal environment process.env.AGENT_ID = 'test-agent'; const { loadConfig } = await import('../../src/config.js'); const config = loadConfig(); expect(config.agentId).toBe('test-agent'); expect(config.networkId).toBe(NetworkId.TestNet); expect(config.walletFilename).toBe('midnight-wallet'); expect(config.logLevel).toBe('info'); expect(config.walletBackupFolder).toBe('.storage/wallet-backups/test-agent'); expect(config.useExternalProofServer).toBe(false); expect(config.walletServerHost).toBe('localhost'); expect(config.walletServerPort).toBe(3000); }); it('should use provided environment variables', async () => { // Set all environment variables process.env.AGENT_ID = 'test-agent'; process.env.NETWORK_ID = 'MainNet'; process.env.WALLET_FILENAME = 'custom-wallet'; process.env.LOG_LEVEL = 'debug'; process.env.WALLET_BACKUP_FOLDER = 'custom-backups'; process.env.WALLET_SERVER_HOST = '0.0.0.0'; process.env.WALLET_SERVER_PORT = '8080'; const { loadConfig } = await import('../../src/config.js'); const config = loadConfig(); expect(config.agentId).toBe('test-agent'); expect(config.networkId).toBe(NetworkId.MainNet); expect(config.walletFilename).toBe('custom-wallet'); expect(config.logLevel).toBe('debug'); expect(config.walletBackupFolder).toBe('custom-backups/test-agent'); expect(config.walletServerHost).toBe('0.0.0.0'); expect(config.walletServerPort).toBe(8080); }); it('should handle invalid network ID gracefully', async () => { process.env.AGENT_ID = 'test-agent'; process.env.NETWORK_ID = 'InvalidNetwork'; const { loadConfig } = await import('../../src/config.js'); const config = loadConfig(); expect(config.networkId).toBe(NetworkId.TestNet); }); it('should handle external proof server configuration when enabled', async () => { process.env.AGENT_ID = 'test-agent'; process.env.USE_EXTERNAL_PROOF_SERVER = 'true'; process.env.PROOF_SERVER = 'https://proof.example.com'; process.env.INDEXER = 'https://indexer.example.com'; process.env.INDEXER_WS = 'wss://indexer-ws.example.com'; process.env.MN_NODE = 'https://node.example.com'; const { loadConfig } = await import('../../src/config.js'); const config = loadConfig(); expect(config.useExternalProofServer).toBe(true); expect(config.proofServer).toBe('https://proof.example.com'); expect(config.indexer).toBe('https://indexer.example.com'); expect(config.indexerWS).toBe('wss://indexer-ws.example.com'); expect(config.node).toBe('https://node.example.com'); }); it('should throw error when external proof server is enabled but required env vars are missing', async () => { process.env.AGENT_ID = 'test-agent'; process.env.USE_EXTERNAL_PROOF_SERVER = 'true'; // Missing PROOF_SERVER, INDEXER, INDEXER_WS, MN_NODE await expect(async () => { const { loadConfig } = await import('../../src/config.js'); loadConfig(); }).rejects.toThrow('Proof server, indexer, indexerWS, and node are required when USE_EXTERNAL_PROOF_SERVER is true'); }); it('should throw error when external proof server is enabled but PROOF_SERVER is missing', async () => { process.env.AGENT_ID = 'test-agent'; process.env.USE_EXTERNAL_PROOF_SERVER = 'true'; process.env.INDEXER = 'https://indexer.example.com'; process.env.INDEXER_WS = 'wss://indexer-ws.example.com'; process.env.MN_NODE = 'https://node.example.com'; // Missing PROOF_SERVER await expect(async () => { const { loadConfig } = await import('../../src/config.js'); loadConfig(); }).rejects.toThrow('Proof server, indexer, indexerWS, and node are required when USE_EXTERNAL_PROOF_SERVER is true'); }); it('should throw error when external proof server is enabled but INDEXER is missing', async () => { process.env.AGENT_ID = 'test-agent'; process.env.USE_EXTERNAL_PROOF_SERVER = 'true'; process.env.PROOF_SERVER = 'https://proof.example.com'; process.env.INDEXER_WS = 'wss://indexer-ws.example.com'; process.env.MN_NODE = 'https://node.example.com'; // Missing INDEXER await expect(async () => { const { loadConfig } = await import('../../src/config.js'); loadConfig(); }).rejects.toThrow('Proof server, indexer, indexerWS, and node are required when USE_EXTERNAL_PROOF_SERVER is true'); }); it('should throw error when external proof server is enabled but INDEXER_WS is missing', async () => { process.env.AGENT_ID = 'test-agent'; process.env.USE_EXTERNAL_PROOF_SERVER = 'true'; process.env.PROOF_SERVER = 'https://proof.example.com'; process.env.INDEXER = 'https://indexer.example.com'; process.env.MN_NODE = 'https://node.example.com'; // Missing INDEXER_WS await expect(async () => { const { loadConfig } = await import('../../src/config.js'); loadConfig(); }).rejects.toThrow('Proof server, indexer, indexerWS, and node are required when USE_EXTERNAL_PROOF_SERVER is true'); }); it('should throw error when external proof server is enabled but MN_NODE is missing', async () => { process.env.AGENT_ID = 'test-agent'; process.env.USE_EXTERNAL_PROOF_SERVER = 'true'; process.env.PROOF_SERVER = 'https://proof.example.com'; process.env.INDEXER = 'https://indexer.example.com'; process.env.INDEXER_WS = 'wss://indexer-ws.example.com'; // Missing MN_NODE await expect(async () => { const { loadConfig } = await import('../../src/config.js'); loadConfig(); }).rejects.toThrow('Proof server, indexer, indexerWS, and node are required when USE_EXTERNAL_PROOF_SERVER is true'); }); it('should handle server port configuration', async () => { process.env.AGENT_ID = 'test-agent'; process.env.SERVER_PORT = '8080'; const { loadConfig } = await import('../../src/config.js'); const config = loadConfig(); // Note: serverPort is not returned in the config object, but the parsing should work expect(config.walletServerPort).toBe(3000); // Default value }); it('should handle wallet server port configuration', async () => { process.env.AGENT_ID = 'test-agent'; process.env.WALLET_SERVER_PORT = '8080'; const { loadConfig } = await import('../../src/config.js'); const config = loadConfig(); expect(config.walletServerPort).toBe(8080); }); it('should handle wallet server host configuration', async () => { process.env.AGENT_ID = 'test-agent'; process.env.WALLET_SERVER_HOST = '0.0.0.0'; const { loadConfig } = await import('../../src/config.js'); const config = loadConfig(); expect(config.walletServerHost).toBe('0.0.0.0'); }); }); describe('fileURLToPath error handling', () => { it('should handle fileURLToPath errors gracefully', async () => { const { fileURLToPath } = await import('url'); (fileURLToPath as jest.MockedFunction<typeof fileURLToPath>).mockImplementation(() => { throw new Error('fileURLToPath error'); }); process.env.AGENT_ID = 'test-agent'; const { loadConfig } = await import('../../src/config.js'); const config = loadConfig(); // Should still work by falling back to process.cwd() expect(config.agentId).toBe('test-agent'); expect(config.networkId).toBe(NetworkId.TestNet); }); }); describe('config singleton', () => { it('should export config singleton', async () => { process.env.AGENT_ID = 'test-agent'; const { config } = await import('../../src/config.js'); expect(config).toBeDefined(); expect(config.agentId).toBe('test-agent'); expect(config.networkId).toBe(NetworkId.TestNet); }); it('should throw error when AGENT_ID is missing in singleton', async () => { await expect(async () => { const { config } = await import('../../src/config.js'); console.log(config); // Just to use the variable }).rejects.toThrow('AGENT_ID environment variable is required'); }); }); });

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/evilpixi/pixi-midnight-mcp'

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