Skip to main content
Glama

tbls MCP Server

by yhosok
uri-patterns-resource.test.ts14.2 kB
import { describe, it, expect } from '@jest/globals'; import { handleUriPatternsResource } from '../../src/resources/uri-patterns-resource'; import type { UriPatternsResource } from '../../src/schemas/database'; describe('URI Patterns Resource Handler', () => { describe('handleUriPatternsResource', () => { it('should return all available URI patterns', async () => { const result = await handleUriPatternsResource(); expect(result.isOk()).toBe(true); if (result.isOk()) { const resource: UriPatternsResource = result.value; expect(resource.patterns).toBeInstanceOf(Array); expect(resource.patterns.length).toBeGreaterThan(0); } }); it('should include schema list pattern', async () => { const result = await handleUriPatternsResource(); expect(result.isOk()).toBe(true); if (result.isOk()) { const resource: UriPatternsResource = result.value; const schemaListPattern = resource.patterns.find( (pattern) => pattern.id === 'db-schemas' ); expect(schemaListPattern).toBeDefined(); expect(schemaListPattern?.uri).toBe('db://schemas'); expect(schemaListPattern?.description).toContain('schemas'); expect(schemaListPattern?.examples).toContain('db://schemas'); expect(schemaListPattern?.parameters).toEqual([]); } }); it('should include schema tables pattern', async () => { const result = await handleUriPatternsResource(); expect(result.isOk()).toBe(true); if (result.isOk()) { const resource: UriPatternsResource = result.value; const schemaTablesPattern = resource.patterns.find( (pattern) => pattern.id === 'db-schema-tables' ); expect(schemaTablesPattern).toBeDefined(); expect(schemaTablesPattern?.uri).toBe( 'db://schemas/{schema_name}/tables' ); expect(schemaTablesPattern?.description).toContain('tables'); expect(schemaTablesPattern?.examples).toContain( 'db://schemas/public/tables' ); expect(schemaTablesPattern?.parameters).toHaveLength(1); expect(schemaTablesPattern?.parameters[0]).toEqual({ name: 'schema_name', description: 'Name of the database schema', required: true, }); } }); it('should include table info pattern', async () => { const result = await handleUriPatternsResource(); expect(result.isOk()).toBe(true); if (result.isOk()) { const resource: UriPatternsResource = result.value; const tableInfoPattern = resource.patterns.find( (pattern) => pattern.id === 'db-table-info' ); expect(tableInfoPattern).toBeDefined(); expect(tableInfoPattern?.uri).toBe( 'db://schemas/{schema_name}/tables/{table_name}' ); expect(tableInfoPattern?.description).toContain('detailed information'); expect(tableInfoPattern?.examples).toContain( 'db://schemas/public/tables/users' ); expect(tableInfoPattern?.parameters).toHaveLength(2); expect(tableInfoPattern?.parameters).toContainEqual({ name: 'schema_name', description: 'Name of the database schema', required: true, }); expect(tableInfoPattern?.parameters).toContainEqual({ name: 'table_name', description: 'Name of the database table', required: true, }); } }); it('should include table indexes pattern', async () => { const result = await handleUriPatternsResource(); expect(result.isOk()).toBe(true); if (result.isOk()) { const resource: UriPatternsResource = result.value; const tableIndexesPattern = resource.patterns.find( (pattern) => pattern.id === 'db-table-indexes' ); expect(tableIndexesPattern).toBeDefined(); expect(tableIndexesPattern?.uri).toBe( 'db://schemas/{schema_name}/tables/{table_name}/indexes' ); expect(tableIndexesPattern?.description).toContain('index'); expect(tableIndexesPattern?.examples).toContain( 'db://schemas/public/tables/users/indexes' ); expect(tableIndexesPattern?.parameters).toHaveLength(2); expect(tableIndexesPattern?.parameters).toContainEqual({ name: 'schema_name', description: 'Name of the database schema', required: true, }); expect(tableIndexesPattern?.parameters).toContainEqual({ name: 'table_name', description: 'Name of the database table', required: true, }); } }); it('should include URI patterns resource pattern itself', async () => { const result = await handleUriPatternsResource(); expect(result.isOk()).toBe(true); if (result.isOk()) { const resource: UriPatternsResource = result.value; const uriPatternsPattern = resource.patterns.find( (pattern) => pattern.id === 'uri-patterns' ); expect(uriPatternsPattern).toBeDefined(); expect(uriPatternsPattern?.uri).toBe('db://uri-patterns'); expect(uriPatternsPattern?.description).toContain('URI patterns'); expect(uriPatternsPattern?.examples).toContain('db://uri-patterns'); expect(uriPatternsPattern?.parameters).toEqual([]); } }); it('should return patterns with all required fields', async () => { const result = await handleUriPatternsResource(); expect(result.isOk()).toBe(true); if (result.isOk()) { const resource: UriPatternsResource = result.value; resource.patterns.forEach((pattern) => { expect(pattern.id).toBeDefined(); expect(typeof pattern.id).toBe('string'); expect(pattern.id.length).toBeGreaterThan(0); expect(pattern.uri).toBeDefined(); expect(typeof pattern.uri).toBe('string'); expect(pattern.uri.length).toBeGreaterThan(0); expect(pattern.description).toBeDefined(); expect(typeof pattern.description).toBe('string'); expect(pattern.description.length).toBeGreaterThan(0); expect(pattern.examples).toBeDefined(); expect(Array.isArray(pattern.examples)).toBe(true); expect(pattern.examples.length).toBeGreaterThan(0); expect(pattern.parameters).toBeDefined(); expect(Array.isArray(pattern.parameters)).toBe(true); pattern.parameters.forEach((param) => { expect(param.name).toBeDefined(); expect(typeof param.name).toBe('string'); expect(param.name.length).toBeGreaterThan(0); expect(param.description).toBeDefined(); expect(typeof param.description).toBe('string'); expect(param.description.length).toBeGreaterThan(0); expect(typeof param.required).toBe('boolean'); }); }); } }); it('should return patterns sorted by ID for consistent ordering', async () => { const result = await handleUriPatternsResource(); expect(result.isOk()).toBe(true); if (result.isOk()) { const resource: UriPatternsResource = result.value; const sortedIds = resource.patterns.map((p) => p.id).sort(); const actualIds = resource.patterns.map((p) => p.id); expect(actualIds).toEqual(sortedIds); } }); it('should include comprehensive examples for each pattern', async () => { const result = await handleUriPatternsResource(); expect(result.isOk()).toBe(true); if (result.isOk()) { const resource: UriPatternsResource = result.value; resource.patterns.forEach((pattern) => { // Each pattern should have at least one example expect(pattern.examples.length).toBeGreaterThanOrEqual(1); // Examples should be valid URIs pattern.examples.forEach((example) => { expect(example).toMatch(/^db:\/\//); }); }); } }); it('should handle empty parameters gracefully', async () => { const result = await handleUriPatternsResource(); expect(result.isOk()).toBe(true); if (result.isOk()) { const resource: UriPatternsResource = result.value; // At least one pattern should have no parameters (like schema://list) const patternsWithoutParams = resource.patterns.filter( (p) => p.parameters.length === 0 ); expect(patternsWithoutParams.length).toBeGreaterThan(0); } }); it('should provide meaningful descriptions for all patterns', async () => { const result = await handleUriPatternsResource(); expect(result.isOk()).toBe(true); if (result.isOk()) { const resource: UriPatternsResource = result.value; resource.patterns.forEach((pattern) => { // Description should be meaningful (more than just the pattern ID) expect(pattern.description.length).toBeGreaterThan(pattern.id.length); // Should contain helpful words const description = pattern.description.toLowerCase(); const helpfulWords = [ 'schema', 'table', 'index', 'list', 'information', 'pattern', 'uri', ]; const containsHelpfulWord = helpfulWords.some((word) => description.includes(word) ); expect(containsHelpfulWord).toBe(true); }); } }); it('should handle parameter extraction correctly for complex patterns', async () => { const result = await handleUriPatternsResource(); expect(result.isOk()).toBe(true); if (result.isOk()) { const resource: UriPatternsResource = result.value; const tableInfoPattern = resource.patterns.find( (p) => p.id === 'db-table-info' ); expect(tableInfoPattern?.parameters).toHaveLength(2); // Check parameter names are converted to snake_case const paramNames = tableInfoPattern?.parameters.map((p) => p.name) || []; expect(paramNames).toContain('schema_name'); expect(paramNames).toContain('table_name'); // Check all parameters are required tableInfoPattern?.parameters.forEach((param) => { expect(param.required).toBe(true); }); } }); it('should provide consistent URI format across all patterns', async () => { const result = await handleUriPatternsResource(); expect(result.isOk()).toBe(true); if (result.isOk()) { const resource: UriPatternsResource = result.value; resource.patterns.forEach((pattern) => { // All URIs should start with db:// protocol expect(pattern.uri).toMatch(/^db:\/\//); // Parameter placeholders should use snake_case const paramMatches = pattern.uri.match(/\{([^}]+)\}/g) || []; paramMatches.forEach((match) => { const paramName = match.slice(1, -1); expect(paramName).toMatch(/^[a-z]+(_[a-z]+)*$/); }); }); } }); it('should provide diverse examples for pattern demonstration', async () => { const result = await handleUriPatternsResource(); expect(result.isOk()).toBe(true); if (result.isOk()) { const resource: UriPatternsResource = result.value; // Patterns with parameters should have multiple examples const patternsWithParams = resource.patterns.filter( (p) => p.parameters.length > 0 ); patternsWithParams.forEach((pattern) => { if (pattern.id !== 'uri-patterns') { expect(pattern.examples.length).toBeGreaterThanOrEqual(1); } }); // Examples should not contain parameter placeholders resource.patterns.forEach((pattern) => { pattern.examples.forEach((example) => { expect(example).not.toMatch(/\{[^}]+\}/); }); }); } }); it('should maintain consistency in pattern ordering', async () => { // Run multiple times to ensure ordering is stable const results = await Promise.all([ handleUriPatternsResource(), handleUriPatternsResource(), handleUriPatternsResource(), ]); results.forEach((result) => expect(result.isOk()).toBe(true)); if (results.every((r) => r.isOk())) { const firstResult = results[0].value as UriPatternsResource; const firstIds = firstResult.patterns.map((p) => p.id); results.slice(1).forEach((result) => { const ids = (result.value as UriPatternsResource).patterns.map( (p) => p.id ); expect(ids).toEqual(firstIds); }); } }); }); describe('helper functions validation', () => { it('should handle patterns without parameters', async () => { const result = await handleUriPatternsResource(); expect(result.isOk()).toBe(true); if (result.isOk()) { const resource: UriPatternsResource = result.value; const schemaListPattern = resource.patterns.find( (p) => p.id === 'db-schemas' ); expect(schemaListPattern?.parameters).toEqual([]); expect(schemaListPattern?.uri).not.toMatch(/\{[^}]+\}/); } }); it('should generate appropriate descriptions for all pattern types', async () => { const result = await handleUriPatternsResource(); expect(result.isOk()).toBe(true); if (result.isOk()) { const resource: UriPatternsResource = result.value; // Check specific description overrides const tableInfoPattern = resource.patterns.find( (p) => p.id === 'db-table-info' ); expect(tableInfoPattern?.description).toContain('detailed information'); const tableIndexesPattern = resource.patterns.find( (p) => p.id === 'db-table-indexes' ); expect(tableIndexesPattern?.description).toContain('index information'); } }); }); });

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/yhosok/tbls-mcp-server'

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