Skip to main content
Glama

Quickbase MCP Server

MIT License
2
4
  • Apple
  • Linux
reports.test.ts7.91 kB
import { RunReportTool } from '../../tools/reports/run_report'; import { QuickbaseClient } from '../../client/quickbase'; import { ApiResponse } from '../../types/api'; jest.mock('../../utils/logger', () => ({ createLogger: jest.fn().mockReturnValue({ error: jest.fn(), warn: jest.fn(), info: jest.fn(), debug: jest.fn() }) })); describe('Report Tools', () => { let mockClient: jest.Mocked<QuickbaseClient>; beforeEach(() => { mockClient = { request: jest.fn() } as any; jest.clearAllMocks(); }); describe('RunReportTool', () => { let tool: RunReportTool; beforeEach(() => { tool = new RunReportTool(mockClient); }); it('should run a report successfully', async () => { const mockResponse: ApiResponse<any> = { success: true, data: { fields: [ { id: 6, label: 'Customer Name', type: 'text' }, { id: 7, label: 'Amount', type: 'numeric' }, { id: 8, label: 'Date', type: 'date' } ], data: [ { '6': { value: 'Acme Corp' }, '7': { value: 1000 }, '8': { value: '2024-01-01' } }, { '6': { value: 'Tech Inc' }, '7': { value: 2500 }, '8': { value: '2024-01-02' } }, { '6': { value: 'Global LLC' }, '7': { value: 1750 }, '8': { value: '2024-01-03' } } ], metadata: { totalRecords: 3, numRecords: 3, skip: 0, top: 200 } } }; mockClient.request.mockResolvedValue(mockResponse); const result = await tool.execute({ report_id: 'abcd1234' }); expect(mockClient.request).toHaveBeenCalledWith({ method: 'POST', path: '/reports/abcd1234/run', body: {} }); expect(result.success).toBe(true); expect(result.data).toEqual(mockResponse); }); it('should run a report with skip and top options', async () => { const mockResponse: ApiResponse<any> = { success: true, data: { fields: [ { id: 6, label: 'Customer Name', type: 'text' } ], data: [ { '6': { value: 'Tech Inc' } }, { '6': { value: 'Global LLC' } } ], metadata: { totalRecords: 10, numRecords: 2, skip: 1, top: 2 } } }; mockClient.request.mockResolvedValue(mockResponse); const result = await tool.execute({ report_id: 'abcd1234', options: { skip: 1, top: 2 } }); expect(mockClient.request).toHaveBeenCalledWith({ method: 'POST', path: '/reports/abcd1234/run', body: { skip: 1, top: 2 } }); expect(result.success).toBe(true); expect(result.data).toEqual(mockResponse); }); it('should run a report with where clause', async () => { const mockResponse: ApiResponse<any> = { success: true, data: { fields: [ { id: 6, label: 'Customer Name', type: 'text' }, { id: 7, label: 'Amount', type: 'numeric' } ], data: [ { '6': { value: 'Tech Inc' }, '7': { value: 2500 } }, { '6': { value: 'Big Corp' }, '7': { value: 3000 } } ], metadata: { totalRecords: 2, numRecords: 2, skip: 0, top: 200 } } }; mockClient.request.mockResolvedValue(mockResponse); const result = await tool.execute({ report_id: 'abcd1234', options: { filters: { "7": { "GT": 2000 } } } }); expect(mockClient.request).toHaveBeenCalledWith({ method: 'POST', path: '/reports/abcd1234/run', body: { filters: { "7": { "GT": 2000 } } } }); expect(result.success).toBe(true); expect(result.data).toEqual(mockResponse); }); it('should run a report with sort options', async () => { const mockResponse: ApiResponse<any> = { success: true, data: { fields: [ { id: 6, label: 'Customer Name', type: 'text' }, { id: 7, label: 'Amount', type: 'numeric' } ], data: [ { '6': { value: 'Big Corp' }, '7': { value: 3000 } }, { '6': { value: 'Tech Inc' }, '7': { value: 2500 } }, { '6': { value: 'Acme Corp' }, '7': { value: 1000 } } ], metadata: { totalRecords: 3, numRecords: 3, skip: 0, top: 200 } } }; mockClient.request.mockResolvedValue(mockResponse); const result = await tool.execute({ report_id: 'abcd1234', options: { sortBy: ['7'] } }); expect(mockClient.request).toHaveBeenCalledWith({ method: 'POST', path: '/reports/abcd1234/run', body: { sortBy: ['7'] } }); expect(result.success).toBe(true); expect(result.data).toEqual(mockResponse); }); it('should run a report with groupBy options', async () => { const mockResponse: ApiResponse<any> = { success: true, data: { fields: [ { id: 10, label: 'Category', type: 'text' }, { id: 7, label: 'Amount', type: 'numeric' } ], data: [ { '10': { value: 'Electronics' }, '7': { value: 5500 } }, { '10': { value: 'Software' }, '7': { value: 3500 } } ], metadata: { totalRecords: 2, numRecords: 2, skip: 0, top: 200 } } }; mockClient.request.mockResolvedValue(mockResponse); const result = await tool.execute({ report_id: 'abcd1234', options: { groupBy: ['10'] } }); expect(mockClient.request).toHaveBeenCalledWith({ method: 'POST', path: '/reports/abcd1234/run', body: { groupBy: ['10'] } }); expect(result.success).toBe(true); expect(result.data).toEqual(mockResponse); }); it('should handle report not found error', async () => { const mockError: ApiResponse<any> = { success: false, error: { code: 404, message: 'Report not found' } }; mockClient.request.mockResolvedValue(mockError); const result = await tool.execute({ report_id: 'nonexistent' }); expect(result.success).toBe(true); expect(result.data).toEqual(mockError); }); it('should handle permission error', async () => { const mockError: ApiResponse<any> = { success: false, error: { code: 403, message: 'User does not have permission to run this report' } }; mockClient.request.mockResolvedValue(mockError); const result = await tool.execute({ report_id: 'restricted-report' }); expect(result.success).toBe(true); expect(result.data).toEqual(mockError); }); it('should handle empty report results', async () => { const mockResponse: ApiResponse<any> = { success: true, data: { fields: [ { id: 6, label: 'Customer Name', type: 'text' } ], data: [], metadata: { totalRecords: 0, numRecords: 0, skip: 0, top: 200 } } }; mockClient.request.mockResolvedValue(mockResponse); const result = await tool.execute({ report_id: 'empty-report' }); expect(result.success).toBe(true); expect(result.data).toEqual(mockResponse); }); }); });

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/danielbushman/MCP-Quickbase'

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