Skip to main content
Glama
tools.test.ts7.98 kB
import { describe, it, expect } from 'vitest'; import { UNLOCK_TOOLS, READ_FUNCTIONS, WRITE_FUNCTIONS, isReadFunction, isWriteFunction } from '../../src/tools.js'; describe('Tools Configuration', () => { describe('UNLOCK_TOOLS array', () => { it('should contain 55 tools', () => { expect(UNLOCK_TOOLS).toHaveLength(55); }); it('should have valid tool structure', () => { UNLOCK_TOOLS.forEach((tool, index) => { expect(tool).toHaveProperty('name'); expect(tool).toHaveProperty('description'); expect(tool).toHaveProperty('inputSchema'); expect(typeof tool.name).toBe('string'); expect(typeof tool.description).toBe('string'); expect(typeof tool.inputSchema).toBe('object'); // Validate tool name is not empty expect(tool.name.length).toBeGreaterThan(0); // Validate description is not empty expect(tool.description.length).toBeGreaterThan(0); // Validate input schema structure expect(tool.inputSchema).toHaveProperty('type'); expect(tool.inputSchema.type).toBe('object'); expect(tool.inputSchema).toHaveProperty('properties'); expect(tool.inputSchema).toHaveProperty('required'); // All tools should require chainId expect(tool.inputSchema.required).toContain('chainId'); expect(tool.inputSchema.properties).toHaveProperty('chainId'); }); }); it('should have unique tool names', () => { const toolNames = UNLOCK_TOOLS.map(tool => tool.name); const uniqueNames = new Set(toolNames); expect(uniqueNames.size).toBe(toolNames.length); }); it('should include all essential Unlock protocol functions', () => { const toolNames = UNLOCK_TOOLS.map(tool => tool.name); const essentialUnlockFunctions = [ 'createLock', 'createUpgradeableLock', 'upgradeLock', 'chainIdRead', 'unlockVersion', 'governanceToken', 'getGlobalTokenSymbol', 'publicLockLatestVersion' ]; essentialUnlockFunctions.forEach(funcName => { expect(toolNames).toContain(funcName); }); }); it('should include essential PublicLock functions', () => { const toolNames = UNLOCK_TOOLS.map(tool => tool.name); const essentialLockFunctions = [ 'balanceOf', 'purchase', 'grantKeys', 'getHasValidKey', 'keyPrice', 'transferFrom', 'updateKeyPricing', 'withdraw' ]; essentialLockFunctions.forEach(funcName => { expect(toolNames).toContain(funcName); }); }); }); describe('Function categorization', () => { it('should have correct read functions count', () => { expect(READ_FUNCTIONS).toHaveLength(38); // Updated for new Unlock functions }); it('should have correct write functions count', () => { expect(WRITE_FUNCTIONS).toHaveLength(17); // Updated for new Unlock functions }); it('should have all functions categorized', () => { const totalCategorized = READ_FUNCTIONS.length + WRITE_FUNCTIONS.length; expect(totalCategorized).toBe(55); // All tools should be categorized }); it('should not have overlapping functions', () => { const readSet = new Set(READ_FUNCTIONS); const writeSet = new Set(WRITE_FUNCTIONS); READ_FUNCTIONS.forEach(func => { expect(writeSet.has(func)).toBe(false); }); }); it('should include new Unlock protocol functions in categorization', () => { const newUnlockReadFunctions = [ 'chainIdRead', 'unlockVersion', 'governanceToken', 'getGlobalTokenSymbol', 'publicLockLatestVersion' ]; const newUnlockWriteFunctions = [ 'createLock', 'createUpgradeableLock', 'upgradeLock' ]; newUnlockReadFunctions.forEach(func => { expect(READ_FUNCTIONS).toContain(func); }); newUnlockWriteFunctions.forEach(func => { expect(WRITE_FUNCTIONS).toContain(func); }); }); }); describe('Helper functions', () => { describe('isReadFunction', () => { it('should correctly identify read functions', () => { const readFunctionSamples = [ 'balanceOf', 'keyPrice', 'getHasValidKey', 'unlockVersion', 'governanceToken' ]; readFunctionSamples.forEach(func => { expect(isReadFunction(func)).toBe(true); }); }); it('should correctly reject write functions', () => { const writeFunctionSamples = [ 'purchase', 'createLock', 'grantKeys', 'upgradeLock' ]; writeFunctionSamples.forEach(func => { expect(isReadFunction(func)).toBe(false); }); }); it('should return false for unknown functions', () => { expect(isReadFunction('unknownFunction')).toBe(false); expect(isReadFunction('')).toBe(false); }); }); describe('isWriteFunction', () => { it('should correctly identify write functions', () => { const writeFunctionSamples = [ 'purchase', 'createLock', 'grantKeys', 'upgradeLock', 'withdraw' ]; writeFunctionSamples.forEach(func => { expect(isWriteFunction(func)).toBe(true); }); }); it('should correctly reject read functions', () => { const readFunctionSamples = [ 'balanceOf', 'keyPrice', 'unlockVersion' ]; readFunctionSamples.forEach(func => { expect(isWriteFunction(func)).toBe(false); }); }); it('should return false for unknown functions', () => { expect(isWriteFunction('unknownFunction')).toBe(false); expect(isWriteFunction('')).toBe(false); }); }); }); describe('Tool input schemas validation', () => { it('should have proper chainId validation in all tools', () => { UNLOCK_TOOLS.forEach(tool => { const chainIdProperty = tool.inputSchema.properties.chainId; expect(chainIdProperty).toBeDefined(); expect(chainIdProperty.type).toBe('number'); expect(chainIdProperty.enum).toEqual([8453, 84532]); }); }); it('should have proper address pattern validation where needed', () => { const addressFields = ['lockAddress', '_keyOwner', '_recipient', '_tokenAddress']; UNLOCK_TOOLS.forEach(tool => { Object.keys(tool.inputSchema.properties).forEach(propName => { if (addressFields.some(field => propName.includes(field.replace('_', '')))) { const property = tool.inputSchema.properties[propName]; if (property.type === 'string') { expect(property.pattern).toBe('^0x[a-fA-F0-9]{40}$'); } } }); }); }); it('should validate specific tool schemas', () => { // Test createLock tool const createLockTool = UNLOCK_TOOLS.find(tool => tool.name === 'createLock'); expect(createLockTool).toBeDefined(); expect(createLockTool!.inputSchema.required).toEqual([ 'chainId', '_lockCreator', '_expirationDuration', '_tokenAddress', '_keyPrice', '_maxNumberOfKeys', '_lockName' ]); // Test balanceOf tool const balanceOfTool = UNLOCK_TOOLS.find(tool => tool.name === 'balanceOf'); expect(balanceOfTool).toBeDefined(); expect(balanceOfTool!.inputSchema.required).toEqual(['chainId', '_keyOwner']); // Test unlockVersion tool const unlockVersionTool = UNLOCK_TOOLS.find(tool => tool.name === 'unlockVersion'); expect(unlockVersionTool).toBeDefined(); expect(unlockVersionTool!.inputSchema.required).toEqual(['chainId']); }); }); });

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/blahkheart/unlock-mcp'

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