Skip to main content
Glama
coolify-tools.test.ts7.45 kB
import { jest } from '@jest/globals'; import { CoolifyTools } from './coolify-tools.js'; import { CoolifyClient } from '../services/coolify-client.js'; // Create a mock client manually const createMockClient = (): jest.Mocked<CoolifyClient> => { return { getVersion: jest.fn(), listTeams: jest.fn(), createApplication: jest.fn(), createEnvironmentVariable: jest.fn(), listApplications: jest.fn(), } as any; }; describe('CoolifyTools', () => { let tools: CoolifyTools; let mockClient: jest.Mocked<CoolifyClient>; beforeEach(() => { mockClient = createMockClient(); tools = new CoolifyTools(mockClient); }); describe('getVersion', () => { it('should return formatted version information', async () => { mockClient.getVersion.mockResolvedValue({ version: '4.0.0', build_date: '2024-01-01', commit_hash: 'abc123', }); const result = await tools.getVersion(); expect(result).toEqual({ content: [{ type: 'text', text: 'Coolify Version: 4.0.0\nBuild Date: 2024-01-01\nCommit: abc123', }], }); }); it('should handle errors gracefully', async () => { mockClient.getVersion.mockRejectedValue({ message: 'API Error', status: 500, }); const result = await tools.getVersion(); expect(result).toEqual({ isError: true, content: [{ type: 'text', text: '[500] API Error' }], }); }); }); describe('listTeams', () => { it('should return formatted list of teams', async () => { mockClient.listTeams.mockResolvedValue([ { id: 1, name: 'Team Alpha', personal_team: false, description: 'Main team', created_at: '2024-01-01', updated_at: '2024-01-01', }, { id: 2, name: 'Personal Team', personal_team: true, created_at: '2024-01-01', updated_at: '2024-01-01', }, ]); const result = await tools.listTeams(); expect(result.content[0].text).toContain('ID: 1'); expect(result.content[0].text).toContain('Name: Team Alpha'); expect(result.content[0].text).toContain('Personal: No'); expect(result.content[0].text).toContain('Description: Main team'); expect(result.content[0].text).toContain('ID: 2'); expect(result.content[0].text).toContain('Name: Personal Team'); expect(result.content[0].text).toContain('Personal: Yes'); }); it('should handle empty results', async () => { mockClient.listTeams.mockResolvedValue([]); const result = await tools.listTeams(); expect(result).toEqual({ content: [{ type: 'text', text: 'No teams found' }], }); }); }); describe('createApplication', () => { it('should validate input and create application', async () => { const input = { project_uuid: 'proj-123', server_uuid: 'srv-123', type: 'public', name: 'Test App', git_repository: 'https://github.com/test/app', git_branch: 'main', }; mockClient.createApplication.mockResolvedValue({ uuid: 'app-123', name: 'Test App', status: 'stopped', build_pack: 'nixpacks', id: 1, environment_id: 1, destination_id: 1, created_at: '2024-01-01', updated_at: '2024-01-01', }); const result = await tools.createApplication(input); expect(mockClient.createApplication).toHaveBeenCalledWith(input); expect(result).toEqual({ content: [{ type: 'text', text: 'Application created successfully!\nUUID: app-123\nName: Test App\nStatus: stopped', }], }); }); it('should handle validation errors', async () => { const input = { // Missing required fields name: 'Test App', }; const result = await tools.createApplication(input); expect('isError' in result && result.isError).toBe(true); expect(mockClient.createApplication).not.toHaveBeenCalled(); }); }); describe('createEnvironmentVariable', () => { it('should create environment variable with proper validation', async () => { const input = { resourceType: 'application', resourceUuid: 'app-123', key: 'NODE_ENV', value: 'production', is_build_time: true, }; mockClient.createEnvironmentVariable.mockResolvedValue({ id: 1, key: 'NODE_ENV', value: 'production', is_build_time: true, is_preview: false, application_id: 123, created_at: '2024-01-01', updated_at: '2024-01-01', }); const result = await tools.createEnvironmentVariable(input); expect(mockClient.createEnvironmentVariable).toHaveBeenCalledWith( 'application', 'app-123', { key: 'NODE_ENV', value: 'production', is_build_time: true, } ); expect(result).toEqual({ content: [{ type: 'text', text: 'Environment variable created: NODE_ENV=production', }], }); }); }); describe('listApplications', () => { it('should return formatted list of applications', async () => { mockClient.listApplications.mockResolvedValue([ { id: 1, uuid: 'app-123', name: 'Web App', status: 'running', build_pack: 'nixpacks', fqdn: 'https://app.example.com', git_repository: 'https://github.com/test/app', git_branch: 'main', environment_id: 1, destination_id: 1, created_at: '2024-01-01', updated_at: '2024-01-01', }, ]); const result = await tools.listApplications(); expect(result.content[0].text).toContain('UUID: app-123'); expect(result.content[0].text).toContain('Name: Web App'); expect(result.content[0].text).toContain('Status: running'); expect(result.content[0].text).toContain('Build Pack: nixpacks'); expect(result.content[0].text).toContain('URL: https://app.example.com'); expect(result.content[0].text).toContain('Repository: https://github.com/test/app'); expect(result.content[0].text).toContain('Branch: main'); }); }); describe('error formatting', () => { it('should format API errors with details', async () => { mockClient.getVersion.mockRejectedValue({ message: 'Validation failed', errors: { name: ['Name is required', 'Name must be unique'], port: ['Port must be a number'], }, status: 422, }); const result = await tools.getVersion(); expect('isError' in result && result.isError).toBe(true); expect(result.content[0].text).toContain('[422] Validation failed'); expect(result.content[0].text).toContain('name: Name is required, Name must be unique'); expect(result.content[0].text).toContain('port: Port must be a number'); }); it('should handle unknown errors', async () => { mockClient.getVersion.mockRejectedValue('Unknown error'); const result = await tools.getVersion(); expect(result).toEqual({ isError: true, content: [{ type: 'text', text: 'An unexpected error occurred' }], }); }); }); });

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/pavelsukhachev/mcp-server-coolify'

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