Skip to main content
Glama
schemas.test.ts8.93 kB
import { describe, it, expect } from 'vitest'; import { ZodError } from 'zod'; import { AddressSchema, ChainIdSchema, UintSchema, BytesSchema, BalanceOfSchema, CreateLockSchema, PurchaseSchema, UnlockVersionSchema, GovernanceTokenSchema, CreateUpgradeableLockSchema, UpgradeLockSchema, FUNCTION_SCHEMAS } from '../../src/schemas.js'; describe('Schema Validation', () => { describe('Base Schemas', () => { describe('AddressSchema', () => { it('should validate correct Ethereum addresses', () => { const validAddresses = [ '0x1234567890123456789012345678901234567890', '0xabcdefABCDEF1234567890123456789012345678', '0x0000000000000000000000000000000000000000' ]; validAddresses.forEach(address => { expect(() => AddressSchema.parse(address)).not.toThrow(); }); }); it('should reject invalid addresses', () => { const invalidAddresses = [ '0x123', // too short '1234567890123456789012345678901234567890', // missing 0x '0xGGGG567890123456789012345678901234567890', // invalid characters '0x12345678901234567890123456789012345678901' // too long ]; invalidAddresses.forEach(address => { expect(() => AddressSchema.parse(address)).toThrow(ZodError); }); }); }); describe('ChainIdSchema', () => { it('should validate supported chain IDs', () => { expect(() => ChainIdSchema.parse(8453)).not.toThrow(); // Base expect(() => ChainIdSchema.parse(84532)).not.toThrow(); // Base Sepolia }); it('should reject unsupported chain IDs', () => { const invalidChainIds = [1, 137, 42161, 1337]; invalidChainIds.forEach(chainId => { expect(() => ChainIdSchema.parse(chainId)).toThrow(ZodError); }); }); }); describe('UintSchema', () => { it('should validate positive integer strings', () => { const validUints = ['0', '1', '123456789', '1000000000000000000']; validUints.forEach(uint => { expect(() => UintSchema.parse(uint)).not.toThrow(); }); }); it('should reject invalid uint strings', () => { const invalidUints = ['-1', '12.34', 'abc', '', '1e10']; invalidUints.forEach(uint => { expect(() => UintSchema.parse(uint)).toThrow(ZodError); }); }); }); describe('BytesSchema', () => { it('should validate hex strings', () => { const validBytes = ['0x', '0x1234', '0xabcdef', '0x1234567890abcdef']; validBytes.forEach(bytes => { expect(() => BytesSchema.parse(bytes)).not.toThrow(); }); }); it('should reject invalid hex strings', () => { const invalidBytes = ['1234', '0xGGGG', 'not-hex']; invalidBytes.forEach(bytes => { expect(() => BytesSchema.parse(bytes)).toThrow(ZodError); }); }); }); }); describe('PublicLock Function Schemas', () => { describe('BalanceOfSchema', () => { it('should validate correct balanceOf parameters', () => { const validParams = { chainId: 8453, lockAddress: '0x1234567890123456789012345678901234567890', _keyOwner: '0xabcdefABCDEF1234567890123456789012345678' }; expect(() => BalanceOfSchema.parse(validParams)).not.toThrow(); }); it('should make lockAddress optional', () => { const validParamsWithoutLock = { chainId: 8453, _keyOwner: '0xabcdefABCDEF1234567890123456789012345678' }; expect(() => BalanceOfSchema.parse(validParamsWithoutLock)).not.toThrow(); }); it('should reject missing required fields', () => { const invalidParams = { chainId: 8453 // missing _keyOwner }; expect(() => BalanceOfSchema.parse(invalidParams)).toThrow(ZodError); }); }); describe('PurchaseSchema', () => { it('should validate correct purchase parameters', () => { const validParams = { chainId: 8453, lockAddress: '0x1234567890123456789012345678901234567890', _values: ['1000000000000000000'], _recipients: ['0xabcdefABCDEF1234567890123456789012345678'], _referrers: ['0x0000000000000000000000000000000000000000'], _keyManagers: ['0xabcdefABCDEF1234567890123456789012345678'], _data: ['0x'] }; expect(() => PurchaseSchema.parse(validParams)).not.toThrow(); }); it('should validate multiple recipients', () => { const validParams = { chainId: 8453, _values: ['1000000000000000000', '2000000000000000000'], _recipients: [ '0x1234567890123456789012345678901234567890', '0xabcdefABCDEF1234567890123456789012345678' ], _referrers: [ '0x0000000000000000000000000000000000000000', '0x0000000000000000000000000000000000000000' ], _keyManagers: [ '0x1234567890123456789012345678901234567890', '0xabcdefABCDEF1234567890123456789012345678' ], _data: ['0x', '0x1234'] }; expect(() => PurchaseSchema.parse(validParams)).not.toThrow(); }); }); }); describe('Unlock Protocol Function Schemas', () => { describe('CreateLockSchema', () => { it('should validate correct createLock parameters', () => { const validParams = { chainId: 8453, _lockCreator: '0x1234567890123456789012345678901234567890', _expirationDuration: '31536000', // 1 year _tokenAddress: '0x0000000000000000000000000000000000000000', // ETH _keyPrice: '1000000000000000000', // 1 ETH _maxNumberOfKeys: '100', _lockName: 'Test Lock' }; expect(() => CreateLockSchema.parse(validParams)).not.toThrow(); }); it('should require all parameters', () => { const incompleteParams = { chainId: 8453, _lockCreator: '0x1234567890123456789012345678901234567890' // missing other required fields }; expect(() => CreateLockSchema.parse(incompleteParams)).toThrow(ZodError); }); }); describe('CreateUpgradeableLockSchema', () => { it('should validate upgradeable lock parameters', () => { const validParams = { chainId: 8453, data: '0x1234567890abcdef' }; expect(() => CreateUpgradeableLockSchema.parse(validParams)).not.toThrow(); }); it('should accept empty data', () => { const validParams = { chainId: 8453, data: '0x' }; expect(() => CreateUpgradeableLockSchema.parse(validParams)).not.toThrow(); }); }); describe('UpgradeLockSchema', () => { it('should validate upgrade parameters', () => { const validParams = { chainId: 8453, lockAddress: '0x1234567890123456789012345678901234567890', version: '15' }; expect(() => UpgradeLockSchema.parse(validParams)).not.toThrow(); }); }); describe('Protocol Info Schemas', () => { it('should validate protocol info requests', () => { const validParams = { chainId: 8453 }; expect(() => UnlockVersionSchema.parse(validParams)).not.toThrow(); expect(() => GovernanceTokenSchema.parse(validParams)).not.toThrow(); }); }); }); describe('FUNCTION_SCHEMAS mapping', () => { it('should include all expected function schemas', () => { const expectedFunctions = [ 'balanceOf', 'purchase', 'createLock', 'createUpgradeableLock', 'upgradeLock', 'unlockVersion', 'governanceToken', 'chainIdRead' ]; expectedFunctions.forEach(funcName => { expect(FUNCTION_SCHEMAS).toHaveProperty(funcName); expect(FUNCTION_SCHEMAS[funcName as keyof typeof FUNCTION_SCHEMAS]).toBeDefined(); }); }); it('should validate real function calls', () => { // Test a read function const balanceOfArgs = { chainId: 8453, _keyOwner: '0x1234567890123456789012345678901234567890' }; expect(() => FUNCTION_SCHEMAS.balanceOf.parse(balanceOfArgs)).not.toThrow(); // Test a write function const purchaseArgs = { chainId: 8453, _values: ['1000000000000000000'], _recipients: ['0x1234567890123456789012345678901234567890'], _referrers: ['0x0000000000000000000000000000000000000000'], _keyManagers: ['0x1234567890123456789012345678901234567890'], _data: ['0x'] }; expect(() => FUNCTION_SCHEMAS.purchase.parse(purchaseArgs)).not.toThrow(); }); }); });

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