Skip to main content
Glama
mock-factory.ts5.27 kB
import { vi } from "vitest"; export interface MockLokaliseApiOptions { failOnMethod?: string; errorCode?: number; errorMessage?: string; delay?: number; } interface MockLokaliseApi { projects: () => { list: ReturnType<typeof vi.fn>; get: ReturnType<typeof vi.fn>; create: ReturnType<typeof vi.fn>; update: ReturnType<typeof vi.fn>; delete: ReturnType<typeof vi.fn>; empty: ReturnType<typeof vi.fn>; }; keys: () => { list: ReturnType<typeof vi.fn>; get: ReturnType<typeof vi.fn>; create: ReturnType<typeof vi.fn>; update: ReturnType<typeof vi.fn>; bulk_update: ReturnType<typeof vi.fn>; delete: ReturnType<typeof vi.fn>; bulk_delete: ReturnType<typeof vi.fn>; }; languages: () => { system_languages: ReturnType<typeof vi.fn>; list: ReturnType<typeof vi.fn>; get: ReturnType<typeof vi.fn>; create: ReturnType<typeof vi.fn>; update: ReturnType<typeof vi.fn>; delete: ReturnType<typeof vi.fn>; }; tasks: () => ReturnType<typeof vi.fn> & Record<string, ReturnType<typeof vi.fn>>; comments: () => ReturnType<typeof vi.fn> & Record<string, ReturnType<typeof vi.fn>>; translations: () => ReturnType<typeof vi.fn> & Record<string, ReturnType<typeof vi.fn>>; contributors: () => ReturnType<typeof vi.fn> & Record<string, ReturnType<typeof vi.fn>>; glossary: () => ReturnType<typeof vi.fn> & Record<string, ReturnType<typeof vi.fn>>; } export function createMockLokaliseApi( options: MockLokaliseApiOptions = {}, ): MockLokaliseApi { // Create mock methods once and reuse them const projectsMock = { list: vi.fn(), get: vi.fn(), create: vi.fn(), update: vi.fn(), delete: vi.fn(), empty: vi.fn(), }; const keysMock = { list: vi.fn(), get: vi.fn(), create: vi.fn(), update: vi.fn(), bulk_update: vi.fn(), delete: vi.fn(), bulk_delete: vi.fn(), }; const languagesMock = { system_languages: vi.fn(), list: vi.fn(), get: vi.fn(), create: vi.fn(), update: vi.fn(), delete: vi.fn(), }; const tasksMock = { list: vi.fn(), get: vi.fn(), create: vi.fn(), update: vi.fn(), delete: vi.fn(), }; const commentsMock = { list_project_comments: vi.fn(), list_key_comments: vi.fn(), get: vi.fn(), create: vi.fn(), delete: vi.fn(), }; const translationsMock = { list: vi.fn(), get: vi.fn(), update: vi.fn(), }; const contributorsMock = { list: vi.fn(), get: vi.fn(), create: vi.fn(), update: vi.fn(), delete: vi.fn(), }; const glossaryMock = { list: vi.fn(), get: vi.fn(), create: vi.fn(), update: vi.fn(), delete: vi.fn(), }; const mockApi = { projects: vi.fn(() => projectsMock), keys: vi.fn(() => keysMock), languages: vi.fn(() => languagesMock), tasks: vi.fn(() => tasksMock), comments: vi.fn(() => commentsMock), translations: vi.fn(() => translationsMock), contributors: vi.fn(() => contributorsMock), glossary: vi.fn(() => glossaryMock), } as unknown as MockLokaliseApi; // Apply error simulation if specified if (options.failOnMethod) { const [domain, method] = options.failOnMethod.split("."); const apiAny = mockApi as unknown as Record<string, unknown>; if (apiAny[domain]) { const domainMock = (apiAny[domain] as () => Record<string, unknown>)(); if (domainMock?.[method]) { const error = new Error( options.errorMessage || `API Error: ${options.errorCode || 500}`, ); domainMock[method] = vi.fn(() => Promise.reject(error)); } } } // Apply delay if specified if (options.delay) { const apiAny = mockApi as unknown as Record< string, () => Record<string, unknown> >; for (const domain of Object.keys(apiAny)) { const domainMethods = apiAny[domain](); for (const method of Object.keys(domainMethods)) { const original = domainMethods[method] as ( ...args: unknown[] ) => unknown; domainMethods[method] = vi.fn(async (...args: unknown[]) => { await new Promise((resolve) => setTimeout(resolve, options.delay)); return original(...args); }); } } } return mockApi; } // Helper function to create paginated responses export function createPaginatedResponse<T>( items: T[], page = 1, limit = 100, total: number = items.length, ) { return { items, totalResults: total, totalPages: Math.ceil(total / limit), resultsPerPage: limit, currentPage: page, hasNextPage: () => page < Math.ceil(total / limit), hasPrevPage: () => page > 1, nextPage: () => page + 1, prevPage: () => page - 1, }; } // Helper function for cursor pagination export function createCursorPaginatedResponse<T>( items: T[], nextCursor: string | null = null, limit = 100, ) { return { items, totalResults: 0, // Not provided in cursor pagination totalPages: 0, resultsPerPage: limit, currentPage: 0, nextCursor, hasNextCursor: () => nextCursor !== null, hasNextPage: () => false, hasPrevPage: () => false, nextPage: () => 0, prevPage: () => 0, }; } // Mock bulk operation response export function mockBulkOperation<T>( successItems: T[], failedItems: Array<{ item: unknown; error: string }>, ) { return { items: successItems, errors: failedItems.map((f) => ({ ...(typeof f.item === "object" && f.item !== null ? f.item : {}), error: { message: f.error }, })), }; }

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/AbdallahAHO/lokalise-mcp'

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