Skip to main content
Glama
AppComponentsService.test.ts3.26 kB
/** * AppComponentsService Tests * * TESTING PATTERNS: * - Unit tests with mocked dependencies * - Test input validation independently * - Cover success cases, edge cases, and error handling * * CODING STANDARDS: * - Use descriptive test names (should...) * - Arrange-Act-Assert pattern * - Mock external dependencies * - Test behavior, not implementation */ import { describe, expect, it, vi } from 'vitest'; // Mock dependencies before importing the service vi.mock('node:fs', () => ({ promises: { readFile: vi.fn(), access: vi.fn(), }, })); vi.mock('glob', () => ({ glob: vi.fn(), })); vi.mock('@agiflowai/aicode-utils', () => ({ log: { info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn(), }, TemplatesManagerService: { getWorkspaceRootSync: vi.fn((): string => '/mock/workspace'), }, })); vi.mock('../../../src/services/StoriesIndexService', () => ({ StoriesIndexService: vi.fn().mockImplementation(() => ({ initialize: vi.fn(), getAllComponents: vi.fn().mockReturnValue([]), })), })); import { AppComponentsService } from '../../../src/services/AppComponentsService'; import type { ListAppComponentsInput } from '../../../src/services/AppComponentsService/types'; describe('AppComponentsService', () => { describe('input validation', () => { it('should throw error when appPath is empty', async () => { const service = new AppComponentsService(); const input: ListAppComponentsInput = { appPath: '', }; await expect(service.listComponents(input)).rejects.toThrow( 'appPath is required and must be a non-empty string', ); }); it('should throw error when appPath is not a string', async () => { const service = new AppComponentsService(); const input = { appPath: null, } as unknown as ListAppComponentsInput; await expect(service.listComponents(input)).rejects.toThrow( 'appPath is required and must be a non-empty string', ); }); it('should throw error when appPath is undefined', async () => { const service = new AppComponentsService(); const input = { appPath: undefined, } as unknown as ListAppComponentsInput; await expect(service.listComponents(input)).rejects.toThrow( 'appPath is required and must be a non-empty string', ); }); it('should throw error when cursor is not a string', async () => { const service = new AppComponentsService(); const input = { appPath: 'apps/test-app', cursor: 123, } as unknown as ListAppComponentsInput; await expect(service.listComponents(input)).rejects.toThrow('cursor must be a string'); }); }); describe('constructor', () => { it('should create instance with default config', () => { const service = new AppComponentsService(); expect(service).toBeDefined(); expect(service).toBeInstanceOf(AppComponentsService); }); it('should create instance with custom config', () => { const service = new AppComponentsService({ pageSize: 50, }); expect(service).toBeDefined(); expect(service).toBeInstanceOf(AppComponentsService); }); }); });

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/AgiFlow/aicode-toolkit'

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